{"id":18600010,"url":"https://github.com/letta-ai/letta","last_synced_at":"2025-12-15T19:49:17.851Z","repository":{"id":199649450,"uuid":"703411624","full_name":"letta-ai/letta","owner":"letta-ai","description":"Letta (formerly MemGPT) is the stateful agents framework with memory, reasoning, and context management.","archived":false,"fork":false,"pushed_at":"2025-04-29T23:39:26.000Z","size":32334,"stargazers_count":16218,"open_issues_count":67,"forks_count":1684,"subscribers_count":130,"default_branch":"main","last_synced_at":"2025-04-30T00:27:57.493Z","etag":null,"topics":["ai","ai-agents","llm","llm-agent"],"latest_commit_sha":null,"homepage":"https://docs.letta.com/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/letta-ai.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":"CITATION.cff","codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2023-10-11T07:38:37.000Z","updated_at":"2025-04-30T00:15:29.000Z","dependencies_parsed_at":"2023-10-25T22:28:32.579Z","dependency_job_id":"522f2fbd-edc6-4c92-bcd8-f245501c2e7c","html_url":"https://github.com/letta-ai/letta","commit_stats":null,"previous_names":["cpacker/memgpt","letta-ai/letta"],"tags_count":106,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/letta-ai%2Fletta","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/letta-ai%2Fletta/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/letta-ai%2Fletta/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/letta-ai%2Fletta/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/letta-ai","download_url":"https://codeload.github.com/letta-ai/letta/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252329796,"owners_count":21730677,"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","ai-agents","llm","llm-agent"],"created_at":"2024-11-07T02:01:19.459Z","updated_at":"2025-12-15T19:49:17.842Z","avatar_url":"https://github.com/letta-ai.png","language":"Python","funding_links":[],"categories":["Python","🤖 AI \u0026 Machine Learning","Generative KI","🤝 Agent Frameworks \u0026 MCP","Design Primitives","Projects and Implementations","Repos","Platforms","HarmonyOS","🧰 Frameworks that Facilitate RAG","Official Resources","🛠️ Tools and Frameworks (Memory Infrastructure)","4. Agentic AI \u0026 Multi-Agent Systems","🤖Generative AI","⚙️ Agent Operations","Table of Open-Source AI Agents Projects","AI Agent Frameworks \u0026 SDKs","✍️ Write Context","Projects","MCP \u0026 Model Context Protocol","5. Agent Memory","Agent Frameworks","Libraries/Frameworks","Agent Infrastructure","Tools","Open Source Tools","AI开源项目","Personal AI Assistant Platforms \u0026 Competitors","LLM Application / RAG","Memory, State, and Communication","Open-source repos","Agent SDKs \u0026 Frameworks","🛠️ Hands-on Projects and Examples","Agent Memory \u0026 Stateful Context","2. Systems \u0026 Frameworks (stateful agents / memory managers)"],"sub_categories":["Agent Frameworks","Memory \u0026 State","Windows Manager","🔧 Framework","🧠 Memory","Cognitive Architecture Frameworks","Long-term memory","AI Agents \u0026 Templates","Agent Memory \u0026 Context","Rust","Memory Management","AI Agent","Stateful Agents","📑 Key Frameworks \u0026 Code Samples","Frameworks \u0026 Tools"],"readme":"\u003cp align=\"center\"\u003e\n  \u003cpicture\u003e\n    \u003csource media=\"(prefers-color-scheme: dark)\" srcset=\"https://raw.githubusercontent.com/letta-ai/letta/refs/heads/main/assets/Letta-logo-RGB_GreyonTransparent_cropped_small.png\"\u003e\n    \u003csource media=\"(prefers-color-scheme: light)\" srcset=\"https://raw.githubusercontent.com/letta-ai/letta/refs/heads/main/assets/Letta-logo-RGB_OffBlackonTransparent_cropped_small.png\"\u003e\n    \u003cimg alt=\"Letta logo\" src=\"https://raw.githubusercontent.com/letta-ai/letta/refs/heads/main/assets/Letta-logo-RGB_GreyonOffBlack_cropped_small.png\" width=\"500\"\u003e\n  \u003c/picture\u003e\n\u003c/p\u003e\n\n# Letta (formerly MemGPT)\n\nLetta is the platform for building stateful agents: open AI with advanced memory that can learn and self-improve over time.\n\n### Quicklinks:\n* [**Developer Documentation**](https://docs.letta.com): Learn how create agents that learn using Python / TypeScript\n* [**Agent Development Environment (ADE)**](https://docs.letta.com/guides/ade/overview): A no-code UI for building stateful agents\n* [**Letta Desktop**](https://docs.letta.com/guides/ade/desktop): A fully-local version of the ADE, available on MacOS and Windows\n* [**Letta Cloud**](https://app.letta.com/): The fastest way to try Letta, with agents running in the cloud\n\n\n## Get started\n\n### [One-Shot ✨ Vibecoding ⚡️ Prompts](https://github.com/letta-ai/letta/blob/main/fern/pages/getting-started/prompts.mdx)\n\nOr install the Letta SDK (available for both Python and TypeScript):\n\n### [Python SDK](https://github.com/letta-ai/letta-python)\n```sh\npip install letta-client\n```\n\n### [TypeScript / Node.js SDK](https://github.com/letta-ai/letta-node)\n```sh\nnpm install @letta-ai/letta-client\n```\n\n## Simple Hello World example\n\nIn the example below, we'll create a stateful agent with two memory blocks, one for itself (the `persona` block), and one for the human. We'll initialize the `human` memory block with incorrect information, and correct agent in our first message - which will trigger the agent to update its own memory with a tool call.\n\n*To run the examples, you'll need to get a `LETTA_API_KEY` from [Letta Cloud](https://app.letta.com/api-keys), or run your own self-hosted server (see [our guide](https://docs.letta.com/guides/selfhosting))*\n\n\n### Python\n```python\nfrom letta_client import Letta\nimport os\n\n# Connect to Letta Cloud (get your API key at https://app.letta.com/api-keys)\nclient = Letta(api_key=os.getenv(\"LETTA_API_KEY\"))\n# client = Letta(base_url=\"http://localhost:8283\", embedding=\"openai/text-embedding-3-small\")  # if self-hosting, set base_url and embedding\n\nagent_state = client.agents.create(\n    model=\"openai/gpt-4.1\",\n    memory_blocks=[\n        {\n          \"label\": \"human\",\n          \"value\": \"The human's name is Chad. They like vibe coding.\"\n        },\n        {\n          \"label\": \"persona\",\n          \"value\": \"My name is Sam, a helpful assistant.\"\n        }\n    ],\n    tools=[\"web_search\", \"run_code\"]\n)\n\nprint(agent_state.id)\n# agent-d9be...0846\n\nresponse = client.agents.messages.create(\n    agent_id=agent_state.id,\n    messages=[\n        {\n            \"role\": \"user\",\n            \"content\": \"Hey, nice to meet you, my name is Brad.\"\n        }\n    ]\n)\n\n# the agent will think, then edit its memory using a tool\nfor message in response.messages:\n    print(message)\n```\n\n### TypeScript / Node.js\n```typescript\nimport { LettaClient } from '@letta-ai/letta-client'\n\n// Connect to Letta Cloud (get your API key at https://app.letta.com/api-keys)\nconst client = new LettaClient({ token: process.env.LETTA_API_KEY });\n// const client = new LettaClient({ baseUrl: \"http://localhost:8283\", embedding: \"openai/text-embedding-3-small\" });  // if self-hosting\n\nconst agentState = await client.agents.create({\n    model: \"openai/gpt-4.1\",\n    memoryBlocks: [\n        {\n          label: \"human\",\n          value: \"The human's name is Chad. They like vibe coding.\"\n        },\n        {\n          label: \"persona\",\n          value: \"My name is Sam, a helpful assistant.\"\n        }\n    ],\n    tools: [\"web_search\", \"run_code\"]\n});\n\nconsole.log(agentState.id);\n// agent-d9be...0846\n\nconst response = await client.agents.messages.create(\n    agentState.id, {\n        messages: [\n            {\n                role: \"user\",\n                content: \"Hey, nice to meet you, my name is Brad.\"\n            }\n        ]\n    }\n);\n\n// the agent will think, then edit its memory using a tool\nfor (const message of response.messages) {\n    console.log(message);\n}\n```\n\n## Core concepts in Letta:\n\nLetta is made by the creators of [MemGPT](https://arxiv.org/abs/2310.08560), a research paper that introduced the concept of the \"LLM Operating System\" for memory management. The core concepts in Letta for designing stateful agents follow the MemGPT LLM OS principles:\n\n1. [**Memory Hierarchy**](https://docs.letta.com/guides/agents/memory): Agents have self-editing memory that is split between in-context memory and out-of-context memory\n2. [**Memory Blocks**](https://docs.letta.com/guides/agents/memory-blocks): The agent's in-context memory is composed of persistent editable **memory blocks**\n3. [**Agentic Context Engineering**](https://docs.letta.com/guides/agents/context-engineering): Agents control the context window by using tools to edit, delete, or search for memory\n4. [**Perpetual Self-Improving Agents**](https://docs.letta.com/guides/agents/overview): Every \"agent\" is a single entity that has a perpetual (infinite) message history\n\n## Multi-agent shared memory ([full guide](https://docs.letta.com/guides/agents/multi-agent-shared-memory))\n\nA single memory block can be attached to multiple agents, allowing to extremely powerful multi-agent shared memory setups.\nFor example, you can create two agents that have their own independent memory blocks in addition to a shared memory block.\n\n### Python\n```python\n# create a shared memory block\nshared_block = client.blocks.create(\n    label=\"organization\",\n    description=\"Shared information between all agents within the organization.\",\n    value=\"Nothing here yet, we should update this over time.\"\n)\n\n# create a supervisor agent\nsupervisor_agent = client.agents.create(\n    model=\"anthropic/claude-3-5-sonnet-20241022\",\n    # blocks created for this agent\n    memory_blocks=[{\"label\": \"persona\", \"value\": \"I am a supervisor\"}],\n    # pre-existing shared block that is \"attached\" to this agent\n    block_ids=[shared_block.id],\n)\n\n# create a worker agent\nworker_agent = client.agents.create(\n    model=\"openai/gpt-4.1-mini\",\n    # blocks created for this agent\n    memory_blocks=[{\"label\": \"persona\", \"value\": \"I am a worker\"}],\n    # pre-existing shared block that is \"attached\" to this agent\n    block_ids=[shared_block.id],\n)\n```\n\n### TypeScript / Node.js\n```typescript\n// create a shared memory block\nconst sharedBlock = await client.blocks.create({\n    label: \"organization\",\n    description: \"Shared information between all agents within the organization.\",\n    value: \"Nothing here yet, we should update this over time.\"\n});\n\n// create a supervisor agent\nconst supervisorAgent = await client.agents.create({\n    model: \"anthropic/claude-3-5-sonnet-20241022\",\n    // blocks created for this agent\n    memoryBlocks: [{ label: \"persona\", value: \"I am a supervisor\" }],\n    // pre-existing shared block that is \"attached\" to this agent\n    blockIds: [sharedBlock.id]\n});\n\n// create a worker agent\nconst workerAgent = await client.agents.create({\n    model: \"openai/gpt-4.1-mini\",\n    // blocks created for this agent\n    memoryBlocks: [{ label: \"persona\", value: \"I am a worker\" }],\n    // pre-existing shared block that is \"attached\" to this agent\n    blockIds: [sharedBlock.id]\n});\n```\n\n## Sleep-time agents ([full guide](https://docs.letta.com/guides/agents/architectures/sleeptime))\n\nIn Letta, you can create special **sleep-time agents** that share the memory of your primary agents, but run in the background (like an agent's \"subconcious\"). You can think of sleep-time agents as a special form of multi-agent architecture.\n\nTo enable sleep-time agents for your agent, set the `enable_sleeptime` flag to true when creating your agent. This will automatically create a sleep-time agent in addition to your main agent which will handle the memory editing, instead of your primary agent.\n\n### Python\n```python\nagent_state = client.agents.create(\n    ...\n    enable_sleeptime=True,  # \u003c- enable this flag to create a sleep-time agent\n)\n```\n\n### TypeScript / Node.js\n```typescript\nconst agentState = await client.agents.create({\n    ...\n    enableSleeptime: true  // \u003c- enable this flag to create a sleep-time agent\n});\n```\n\n## Saving and sharing agents with Agent File (`.af`) ([full guide](https://docs.letta.com/guides/agents/agent-file))\n\nIn Letta, all agent data is persisted to disk (Postgres or SQLite), and can be easily imported and exported using the open source [Agent File](https://github.com/letta-ai/agent-file) (`.af`) file format. You can use Agent File to checkpoint your agents, as well as move your agents (and their complete state/memories) between different Letta servers, e.g. between self-hosted Letta and Letta Cloud.\n\n\u003cdetails\u003e\n\u003csummary\u003eView code snippets\u003c/summary\u003e\n\n### Python\n```python\n# Import your .af file from any location\nagent_state = client.agents.import_agent_serialized(file=open(\"/path/to/agent/file.af\", \"rb\"))\n\nprint(f\"Imported agent: {agent.id}\")\n\n# Export your agent into a serialized schema object (which you can write to a file)\nschema = client.agents.export_agent_serialized(agent_id=\"\u003cAGENT_ID\u003e\")\n```\n\n### TypeScript / Node.js\n```typescript\nimport { readFileSync } from 'fs';\nimport { Blob } from 'buffer';\n\n// Import your .af file from any location\nconst file = new Blob([readFileSync('/path/to/agent/file.af')])\nconst agentState = await client.agents.importAgentSerialized(file, {})\n\nconsole.log(`Imported agent: ${agentState.id}`);\n\n// Export your agent into a serialized schema object (which you can write to a file)\nconst schema = await client.agents.exportAgentSerialized(\"\u003cAGENT_ID\u003e\");\n```\n\u003c/details\u003e\n\n## Model Context Protocol (MCP) and custom tools ([full guide](https://docs.letta.com/guides/mcp/overview))\n\nLetta has rich support for MCP tools (Letta acts as an MCP client), as well as custom Python tools.\nMCP servers can be easily added within the Agent Development Environment (ADE) tool manager UI, as well as via the SDK:\n\n\n\u003cdetails\u003e\n\u003csummary\u003eView code snippets\u003c/summary\u003e\n\n### Python\n```python\n# List tools from an MCP server\ntools = client.tools.list_mcp_tools_by_server(mcp_server_name=\"weather-server\")\n\n# Add a specific tool from the MCP server\ntool = client.tools.add_mcp_tool(\n    mcp_server_name=\"weather-server\",\n    mcp_tool_name=\"get_weather\"\n)\n\n# Create agent with MCP tool attached\nagent_state = client.agents.create(\n    model=\"openai/gpt-4o-mini\",\n    tool_ids=[tool.id]\n)\n\n# Or attach tools to an existing agent\nclient.agents.tool.attach(\n    agent_id=agent_state.id\n    tool_id=tool.id\n)\n\n# Use the agent with MCP tools\nresponse = client.agents.messages.create(\n    agent_id=agent_state.id,\n    messages=[\n        {\n            \"role\": \"user\",\n            \"content\": \"Use the weather tool to check the forecast\"\n        }\n    ]\n)\n```\n\n### TypeScript / Node.js\n```typescript\n// List tools from an MCP server\nconst tools = await client.tools.listMcpToolsByServer(\"weather-server\");\n\n// Add a specific tool from the MCP server\nconst tool = await client.tools.addMcpTool(\"weather-server\", \"get_weather\");\n\n// Create agent with MCP tool\nconst agentState = await client.agents.create({\n    model: \"openai/gpt-4o-mini\",\n    toolIds: [tool.id]\n});\n\n// Use the agent with MCP tools\nconst response = await client.agents.messages.create(agentState.id, {\n    messages: [\n        {\n            role: \"user\",\n            content: \"Use the weather tool to check the forecast\"\n        }\n    ]\n});\n```\n\u003c/details\u003e\n\n## Filesystem ([full guide](https://docs.letta.com/guides/agents/filesystem))\n\nLetta’s filesystem allow you to easily connect your agents to external files, for example: research papers, reports, medical records, or any other data in common text formats (`.pdf`, `.txt`, `.md`, `.json`, etc).\nOnce you attach a folder to an agent, the agent will be able to use filesystem tools (`open_file`, `grep_file`, `search_file`) to browse the files to search for information.\n\n\u003cdetails\u003e\n\u003csummary\u003eView code snippets\u003c/summary\u003e\n\n### Python\n```python\n# create the folder (embeddings managed automatically by Letta Cloud)\nfolder = client.folders.create(\n    name=\"my_folder\"\n)\n\n# upload a file into the folder\njob = client.folders.files.upload(\n    folder_id=folder.id,\n    file=open(\"my_file.txt\", \"rb\")\n)\n\n# wait until the job is completed\nwhile True:\n    job = client.jobs.retrieve(job.id)\n    if job.status == \"completed\":\n        break\n    elif job.status == \"failed\":\n        raise ValueError(f\"Job failed: {job.metadata}\")\n    print(f\"Job status: {job.status}\")\n    time.sleep(1)\n\n# once you attach a folder to an agent, the agent can see all files in it\nclient.agents.folders.attach(agent_id=agent.id, folder_id=folder.id)\n\nresponse = client.agents.messages.create(\n    agent_id=agent_state.id,\n    messages=[\n        {\n            \"role\": \"user\",\n            \"content\": \"What data is inside of my_file.txt?\"\n        }\n    ]\n)\n\nfor message in response.messages:\n    print(message)\n```\n\n### TypeScript / Node.js\n```typescript\n// create the folder (embeddings managed automatically by Letta Cloud)\nconst folder = await client.folders.create({\n    name: \"my_folder\"\n});\n\n// upload a file into the folder\nconst uploadJob = await client.folders.files.upload(\n    createReadStream(\"my_file.txt\"),\n    folder.id,\n);\nconsole.log(\"file uploaded\")\n\n// wait until the job is completed\nwhile (true) {\n    const job = await client.jobs.retrieve(uploadJob.id);\n    if (job.status === \"completed\") {\n        break;\n    } else if (job.status === \"failed\") {\n        throw new Error(`Job failed: ${job.metadata}`);\n    }\n    console.log(`Job status: ${job.status}`);\n    await new Promise((resolve) =\u003e setTimeout(resolve, 1000));\n}\n\n// list files in the folder\nconst files = await client.folders.files.list(folder.id);\nconsole.log(`Files in folder: ${files}`);\n\n// list passages in the folder\nconst passages = await client.folders.passages.list(folder.id);\nconsole.log(`Passages in folder: ${passages}`);\n\n// once you attach a folder to an agent, the agent can see all files in it\nawait client.agents.folders.attach(agent.id, folder.id);\n\nconst response = await client.agents.messages.create(\n    agentState.id, {\n        messages: [\n            {\n                role: \"user\",\n                content: \"What data is inside of my_file.txt?\"\n            }\n        ]\n    }\n);\n\nfor (const message of response.messages) {\n    console.log(message);\n}\n```\n\u003c/details\u003e\n\n## Long-running agents ([full guide](https://docs.letta.com/guides/agents/long-running))\n\nWhen agents need to execute multiple tool calls or perform complex operations (like deep research, data analysis, or multi-step workflows), processing time can vary significantly. Letta supports both a background mode (with resumable streaming) as well as an async mode (with polling) to enable robust long-running agent executions.\n\n\n\u003cdetails\u003e\n\u003csummary\u003eView code snippets\u003c/summary\u003e\n\n### Python\n```python\nstream = client.agents.messages.create_stream(\n    agent_id=agent_state.id,\n    messages=[\n      {\n        \"role\": \"user\",\n        \"content\": \"Run comprehensive analysis on this dataset\"\n      }\n    ],\n    stream_tokens=True,\n    background=True,\n)\nrun_id = None\nlast_seq_id = None\nfor chunk in stream:\n    if hasattr(chunk, \"run_id\") and hasattr(chunk, \"seq_id\"):\n        run_id = chunk.run_id       # Save this to reconnect if your connection drops\n        last_seq_id = chunk.seq_id  # Save this as your resumption point for cursor-based pagination\n    print(chunk)\n\n# If disconnected, resume from last received seq_id:\nfor chunk in client.runs.stream(run_id, starting_after=last_seq_id):\n    print(chunk)\n```\n\n### TypeScript / Node.js\n```typescript\nconst stream = await client.agents.messages.createStream({\n    agentId: agentState.id,\n    requestBody: {\n        messages: [\n            {\n                role: \"user\",\n                content: \"Run comprehensive analysis on this dataset\"\n            }\n        ],\n        streamTokens: true,\n        background: true,\n    }\n});\n\nlet runId = null;\nlet lastSeqId = null;\nfor await (const chunk of stream) {\n    if (chunk.run_id \u0026\u0026 chunk.seq_id) {\n        runId = chunk.run_id;      // Save this to reconnect if your connection drops\n        lastSeqId = chunk.seq_id; // Save this as your resumption point for cursor-based pagination\n    }\n    console.log(chunk);\n}\n\n// If disconnected, resume from last received seq_id\nfor await (const chunk of client.runs.stream(runId, {startingAfter: lastSeqId})) {\n    console.log(chunk);\n}\n```\n\u003c/details\u003e\n\n## Using local models\n\nLetta is model agnostic and supports using local model providers such as [Ollama](https://docs.letta.com/guides/server/providers/ollama) and [LM Studio](https://docs.letta.com/guides/server/providers/lmstudio). You can also easily swap models inside an agent after the agent has been created, by modifying the agent state with the new model provider via the SDK or in the ADE.\n\n## Development (only needed if you need to modify the server code)\n\n*Note: this repostory contains the source code for the core Letta service (API server), not the client SDKs. The client SDKs can be found here: [Python](https://github.com/letta-ai/letta-python), [TypeScript](https://github.com/letta-ai/letta-node).*\n\nTo install the Letta server from source, fork the repo, clone your fork, then use [uv](https://docs.astral.sh/uv/getting-started/installation/) to install from inside the main directory:\n```sh\ncd letta\nuv sync --all-extras\n```\n\nTo run the Letta server from source, use `uv run`:\n```sh\nuv run letta server\n```\n\n## Contributing\n\nLetta is an open source project built by over a hundred contributors. There are many ways to get involved in the Letta OSS project!\n\n* [**Join the Discord**](https://discord.gg/letta): Chat with the Letta devs and other AI developers.\n* [**Chat on our forum**](https://forum.letta.com/): If you're not into Discord, check out our developer forum.\n* **Follow our socials**: [Twitter/X](https://twitter.com/Letta_AI), [LinkedIn](https://www.linkedin.com/in/letta), [YouTube](https://www.youtube.com/@letta-ai)\n\n---\n\n***Legal notices**: By using Letta and related Letta services (such as the Letta endpoint or hosted service), you are agreeing to our [privacy policy](https://www.letta.com/privacy-policy) and [terms of service](https://www.letta.com/terms-of-service).*\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fletta-ai%2Fletta","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fletta-ai%2Fletta","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fletta-ai%2Fletta/lists"}