Files
connectai/package.json
T

451 lines
19 KiB
JSON
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{
"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.1.9",
"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": [
"onStartupFinished"
],
"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.openChat",
"title": "Astra: Open Chat (Editor Column)",
"icon": "$(comment-discussion)"
},
{
"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"
},
{
"command": "g1nation.architecture.refresh",
"title": "Astra: Refresh Project Architecture Context"
},
{
"command": "g1nation.architecture.detach",
"title": "Astra: Detach Project Architecture Context"
},
{
"command": "g1nation.architecture.attach",
"title": "Astra: Attach Project Architecture Context"
},
{
"command": "g1nation.architecture.open",
"title": "Astra: Open Project Architecture Doc"
},
{
"command": "g1nation.company.toggle",
"title": "Astra: Toggle 1인 기업 Mode"
},
{
"command": "g1nation.company.manage",
"title": "Astra: Manage 1인 기업 Agents"
},
{
"command": "g1nation.company.openSessions",
"title": "Astra: Open 1인 기업 Sessions Folder"
}
],
"keybindings": [
{
"command": "g1nation.focusChat",
"key": "cmd+l",
"mac": "cmd+l"
}
],
"menus": {
"editor/context": [
{
"command": "g1nation.explainSelection",
"when": "editorHasSelection",
"group": "1_modification"
}
]
},
"viewsContainers": {
"activitybar": [
{
"id": "astra-activity",
"title": "Astra",
"icon": "assets/icon-activitybar.svg"
}
]
},
"views": {
"astra-activity": [
{
"id": "astra-launcher",
"name": "Astra Launcher"
}
]
},
"viewsWelcome": [
{
"view": "astra-launcher",
"contents": "✦ **Astra** — 로컬 AI 인텔리전스 레이어\n\nChat 탭을 닫았을 때 여기서 다시 열 수 있습니다.\n\n[$(comment-discussion) Open Chat](command:g1nation.openChat)\n[$(add) New Chat](command:g1nation.newChat)\n[$(gear) Settings](command:g1nation.settings.focus)\n\n---\n\n**1인 기업 모드**\n\n[$(organization) Manage Agents](command:g1nation.company.manage)\n[$(folder-opened) Open Sessions Folder](command:g1nation.company.openSessions)\n\n---\n\n**Project Architecture**\n\n[$(file-text) Open Architecture Doc](command:g1nation.architecture.open)\n[$(refresh) Refresh Architecture](command:g1nation.architecture.refresh)\n\n---\n\n**Lessons / Knowledge**\n\n[$(lightbulb) Manage Lessons](command:g1nation.lesson.manage)\n[$(edit) Edit Agent ↔ Knowledge Map](command:g1nation.skills.editKnowledgeMap)"
}
],
"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": 0,
"minimum": 0,
"description": "Optional safety knob, OFF by default (0). Some very small models (≤3B) emit an empty/EOS response when given a prompt near their context window even though it nominally fits. If you observe that with a tiny model, set this to e.g. 819216384: for ≤3B models only, Astra then budgets the prompt against this smaller effective window instead of g1nation.contextLength. Never applies to 4B+ models. Leave 0 unless you actually hit the issue — it reduces the output-token budget. Default: 0 (disabled)"
},
"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. 56) 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 (<think>, <|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 '<workspace>/.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 '<workspace>/.agent/skills'. Use this on Windows or when your skills live outside the workspace."
},
"g1nation.embeddingModel": {
"type": "string",
"default": "",
"description": "Embedding model registered in LM Studio / Ollama (e.g. 'text-embedding-bge-small-en-v1.5', 'nomic-embed-text', 'multilingual-e5-small'). When empty, Astra uses TF-IDF only. When set, the brain is embedded lazily in the background and retrieval blends TF-IDF + cosine similarity for synonym / paraphrase matching. Multilingual models are recommended for Korean content."
},
"g1nation.embeddingBlendAlpha": {
"type": "number",
"default": 0.5,
"minimum": 0,
"maximum": 1,
"description": "Hybrid score blend: 0 = pure TF-IDF (sparse / keyword), 1 = pure embedding cosine (dense / semantic), 0.5 = balanced. Only used when g1nation.embeddingModel is set. Default 0.5."
},
"g1nation.knowledgeMix.secondBrainWeight": {
"type": "number",
"default": 50,
"minimum": 0,
"maximum": 100,
"description": "Knowledge Mix (0100): how heavily the assistant should lean on Second Brain evidence vs. its own general knowledge. 0 = Second Brain disabled (model knowledge only). 50 = balanced (legacy default). 100 = Second Brain is the primary evidence; model knowledge only fills harmless background. Per-agent overrides in the Agent Mapping panel win over this global value."
},
"g1nation.enableReflection": {
"type": "boolean",
"default": true,
"description": "Insert a Self-Reflection (Reflector) stage between Researcher and Writer in the multi-agent workflow. The Reflector critically reviews the plan and research output (gaps, contradictions, unsupported claims, drift from the original objective) and feeds a structured critique to the Writer, which must address it before producing the final report. Reflection failures are non-fatal (the Writer still runs with empty critique). Disable to save one LLM call per mission if you prioritize latency or are running on a very small model."
},
"g1nation.autoLessonFromReflection": {
"type": "boolean",
"default": true,
"description": "Persist substantive Reflector critiques to the active brain as lesson cards under `lessons/auto-reflector/`. Future missions automatically retrieve these cards (via the existing Experience-Memory pipeline) and inject them as [⚠ ACTIVE LESSONS — verify these BEFORE finalizing] guardrails into Planner/Researcher/Writer context. A repeated critique (similar title) bumps `occurrences` and escalates `severity` (low→medium→high) instead of duplicating the card, so recurring patterns get louder over time. Disable to keep critiques single-mission only."
}
}
}
},
"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"
}
}