{ "name": "astra", "displayName": "Astra", "description": "The personal intelligence layer for Antigravity and VS Code. A private cognitive partner for deep project context, memory, and proactive strategic decision-making.", "version": "2.80.39", "publisher": "g1nation", "license": "MIT", "icon": "assets/icon.png", "repository": { "type": "git", "url": "https://github.com/g1nations/locallm" }, "engines": { "vscode": "^1.80.0" }, "categories": [ "Machine Learning", "Programming Languages", "Chat" ], "keywords": [ "ai", "local", "ollama", "gemma", "llama", "deepseek", "offline", "agent", "code-generation", "astra", "copilot" ], "activationEvents": [], "main": "./out/extension.js", "contributes": { "commands": [ { "command": "g1nation.newChat", "title": "Astra: New Chat", "icon": "$(add)" }, { "command": "g1nation.exportChat", "title": "Astra: Export Chat as Markdown" }, { "command": "g1nation.explainSelection", "title": "Astra: Explain Selected Code" }, { "command": "g1nation.focusChat", "title": "Astra: Focus Chat Input" }, { "command": "g1nation.showBrainNetwork", "title": "Astra: Show Brain Topology" }, { "command": "g1nation.approval.focus", "title": "Astra: Focus Approval Panel" }, { "command": "g1nation.scaffoldProject", "title": "Astra: Scaffold New Project" }, { "command": "g1nation.telegram.setBotToken", "title": "Astra: Set Telegram Bot Token" }, { "command": "g1nation.telegram.clearBotToken", "title": "Astra: Clear Telegram Bot Token" }, { "command": "g1nation.telegram.testConnection", "title": "Astra: Test Telegram Connection" }, { "command": "g1nation.settings.focus", "title": "Astra: Open Settings Panel" }, { "command": "g1nation.skills.editKnowledgeMap", "title": "Astra: Edit Agent ↔ Knowledge Map" }, { "command": "g1nation.lesson.create", "title": "Astra: New Lesson (Experience Memory)" }, { "command": "g1nation.lesson.fromConversation", "title": "Astra: New Lesson from Current Conversation" }, { "command": "g1nation.lesson.manage", "title": "Astra: Browse / Manage Lessons" } ], "keybindings": [ { "command": "g1nation.focusChat", "key": "cmd+l", "mac": "cmd+l" } ], "menus": { "editor/context": [ { "command": "g1nation.explainSelection", "when": "editorHasSelection", "group": "1_modification" } ] }, "viewsContainers": { "activitybar": [ { "id": "g1nation-sidebar", "title": "Astra", "icon": "$(hubot)" } ] }, "views": { "g1nation-sidebar": [ { "type": "webview", "id": "g1nation-v2-view", "name": "Chat", "icon": "assets/icon.png" }, { "type": "webview", "id": "g1nation-approval-panel", "name": "Pending Approvals", "icon": "$(check)" }, { "type": "webview", "id": "g1nation-settings-panel", "name": "Settings", "icon": "$(gear)" } ] }, "configuration": { "title": "Astra", "properties": { "g1nation.multiAgentEnabled": { "type": "boolean", "default": false, "description": "Enable Multi-Agent Workflow (Planner -> Researcher -> Writer) for complex tasks." }, "g1nation.memoryEnabled": { "type": "boolean", "default": true, "description": "Enable layered memory injection before each model response." }, "g1nation.memoryShortTermMessages": { "type": "number", "default": 8, "minimum": 0, "description": "Number of recent conversation messages included as short-term memory." }, "g1nation.memoryMediumTermSessions": { "type": "number", "default": 5, "minimum": 0, "description": "Number of recent saved chat sessions included as medium-term memory." }, "g1nation.memoryLongTermFiles": { "type": "number", "default": 6, "minimum": 0, "description": "Number of relevant Second Brain markdown files included as long-term memory." }, "g1nation.ollamaUrl": { "type": "string", "default": "http://127.0.0.1:11434", "description": "Base URL for Ollama or LM Studio. Default: http://127.0.0.1:11434" }, "g1nation.defaultModel": { "type": "string", "default": "gemma4:e2b", "description": "Default model name to use for chat requests." }, "g1nation.requestTimeout": { "type": "number", "default": 300, "description": "Request timeout in seconds. Default: 300" }, "g1nation.contextLength": { "type": "number", "default": 32768, "minimum": 2048, "description": "Model context window in tokens (prompt + generation combined). Set this to the value your loaded model is actually running with in LM Studio / Ollama. Astra budgets prompt and output against this so it never overflows. Default: 32768" }, "g1nation.maxOutputTokens": { "type": "number", "default": 4096, "minimum": 256, "description": "Upper bound on tokens generated per response. The effective limit is reduced automatically when the prompt is large so input + output stays within g1nation.contextLength. Default: 4096" }, "g1nation.contextSafetyMargin": { "type": "number", "default": 2048, "minimum": 0, "description": "Tokens kept free as a safety buffer for token-count estimation error. Default: 2048" }, "g1nation.contextOverflowPolicy": { "type": "string", "enum": [ "stopAtLimit", "truncateMiddle", "rollingWindow" ], "default": "stopAtLimit", "description": "Fallback behavior (LM Studio) if the prompt still exceeds the context window after Astra's own budgeting. 'stopAtLimit' fails clearly so you notice; 'truncateMiddle'/'rollingWindow' drop content silently. Default: stopAtLimit" }, "g1nation.autoCompactHistory": { "type": "boolean", "default": true, "description": "Automatically drop the oldest conversation messages from the request when the prompt would exceed the context budget (the on-screen chat history is unaffected). Default: true" }, "g1nation.smallModelContextCap": { "type": "number", "default": 16384, "minimum": 0, "description": "When a genuinely tiny model (≤3B parameters, detected from the model name) is selected, budget the prompt against this smaller effective context window instead of g1nation.contextLength — very small models can emit an empty/EOS response on prompts that nominally fit but exceed their real capability. Does NOT apply to 4B+ models. Set 0 to disable entirely. Default: 16384" }, "g1nation.autoContinueOnOutputLimit": { "type": "boolean", "default": true, "description": "When a reply is cut off because it hit the output-token limit, Astra continues it internally (compressed request — original question + the answer so far, not the whole context again) and shows one merged answer, instead of asking you to say \"이어서 작성해줘\". Default: true" }, "g1nation.maxAutoContinuations": { "type": "number", "default": 4, "minimum": 0, "maximum": 10, "description": "Maximum number of automatic continuation rounds per reply (prevents runaway loops). Raise it (e.g. 5–6) for long-form answers on slow local models; set 0 to disable auto-continuation. Default: 4" }, "g1nation.finalOnlyRetryOnThoughtLeak": { "type": "boolean", "default": true, "description": "If the model emits only hidden reasoning (, <|channel|>thought, \"Thinking Process:\" …) and no user-visible answer, Astra silently re-asks it for the final answer only. Hidden reasoning is never shown either way. Default: true" }, "g1nation.lmStudio.idleTimeoutMs": { "type": "number", "default": 300000, "minimum": 0, "description": "Auto-eject the loaded LM Studio model after this many milliseconds of inactivity. Set to 0 to disable. Default: 300000 (5 minutes)." }, "g1nation.lmStudio.autoLoadOnSelect": { "type": "boolean", "default": true, "description": "Automatically load LM Studio models into memory when selected from the Astra sidebar." }, "g1nation.localBrainPath": { "type": "string", "default": "", "description": "Folder path for your local Second Brain knowledge base. Leave empty to use the default folder." }, "g1nation.brainProfiles": { "type": "array", "default": [], "items": { "type": "object", "properties": { "id": { "type": "string", "description": "Stable brain profile id." }, "name": { "type": "string", "description": "Display name shown in the Astra brain selector." }, "localBrainPath": { "type": "string", "description": "Local folder path used as this brain's markdown knowledge base." }, "secondBrainRepo": { "type": "string", "description": "Optional Git repository URL for this brain." }, "description": { "type": "string", "description": "Short note shown under the active brain status." } } }, "description": "Multiple brain profiles. Each item supports id, name, localBrainPath, secondBrainRepo, and description." }, "g1nation.activeBrainId": { "type": "string", "default": "", "description": "Active brain profile id used for the current chat context." }, "g1nation.secondBrainRepo": { "type": "string", "default": "", "description": "Optional GitHub repository URL used for Second Brain sync." }, "g1nation.autoPushBrain": { "type": "boolean", "default": false, "description": "Automatically commit and push Second Brain changes after updates." }, "g1nation.maxContextSize": { "type": "number", "default": 32000, "description": "Maximum character count for active file context. Default: 32000" }, "g1nation.maxAutoSteps": { "type": "number", "default": 50, "description": "Maximum autonomous steps the agent can take per request. Default: 50" }, "g1nation.dryRun": { "type": "boolean", "default": false, "description": "If enabled, the agent will ask for approval before committing any file changes." }, "g1nation.telegram.enabled": { "type": "boolean", "default": false, "description": "Enable the Telegram bot integration. When on, Astra polls a bot you configure and replies to incoming messages. Off by default — Astra remains 100% local until you opt in." }, "g1nation.telegram.allowedChatIds": { "type": "array", "default": [], "items": { "type": "number" }, "description": "Optional allowlist of Telegram chat IDs that may message the bot. When empty, every chat that messages the bot is accepted (use with caution)." }, "g1nation.telegram.defaultAgent": { "type": "string", "default": "", "description": "Agent name (matches an entry in the Agent ↔ Knowledge map) used to scope Second Brain retrieval for Telegram replies. Empty falls back to the map's defaultAgent, then to whole-brain search." }, "g1nation.telegram.agentByChatId": { "type": "object", "default": {}, "additionalProperties": { "type": "string" }, "description": "Per-chat override of the Telegram agent. Keys are stringified chat IDs, values are agent names from the knowledge map. Overrides telegram.defaultAgent for the listed chats." }, "g1nation.telegram.contextChunks": { "type": "number", "default": 6, "minimum": 0, "maximum": 20, "description": "How many Second Brain excerpts to inject into Telegram replies. Set 0 to disable RAG (plain prompt only)." }, "g1nation.skillKnowledgeMapPath": { "type": "string", "default": "", "description": "Absolute path to the agent ↔ knowledge mapping JSON. When empty, defaults to '/.astra/agent-knowledge-map.json'." }, "g1nation.skillKnowledgeMap": { "type": "object", "default": {}, "description": "Inline fallback for the agent ↔ knowledge mapping. Used only when the JSON file is missing. Shape: { defaultAgent?, agents: [{ name, knowledgeFolders, model?, description? }] }. Folder paths can be absolute, ~-prefixed, or relative to the active brain root." }, "g1nation.agentSkillsPath": { "type": "string", "default": "", "description": "Absolute path to the agent skills folder (`.agent/skills/*.md`). When empty, defaults to '/.agent/skills'. Use this on Windows or when your skills live outside the workspace." } } } }, "scripts": { "vscode:prepublish": "npm run test && npm run compile", "compile": "esbuild src/extension.ts --bundle --platform=node --external:vscode --outfile=out/extension.js", "watch": "tsc -watch -p ./", "test": "jest --no-cache --forceExit", "test:engine": "jest tests/agentEngine.test.ts --verbose --no-cache", "pretest": "npm run compile" }, "devDependencies": { "@types/jest": "^29.5.14", "@types/node": "18.x", "@types/vscode": "^1.80.0", "@vercel/ncc": "^0.38.4", "esbuild": "^0.28.0", "jest": "^29.7.0", "ts-jest": "^29.4.9", "typescript": "^5.1.3" }, "dependencies": { "@lmstudio/sdk": "^1.5.0", "pdf-parse": "^2.4.5" } }