Files
lam-agent-vicinae/package.json
T
adrianbonpin 36d7d2fdea feat: file access preferences
Three settings: the switch, and the two root fields. Off by default, because the
read half of this feature cannot ask before it happens, and `ipGeolocation` in this
repository is already off for the weaker version of the same reason.

The manifest keeps the file's own formatting rather than prettier's, since the
repository's format script has never covered package.json.
2026-10-07 17:00:52 +08:00

229 lines
9.5 KiB
JSON

{
"$schema": "https://raw.githubusercontent.com/vicinaehq/vicinae/refs/heads/main/extra/schemas/extension.json",
"name": "lam-agent",
"title": "Lam Agent",
"description": "Agentic AI chat powered by Ollama. Ask anything from a global hotkey, with streaming answers, persistent sessions, and web search.",
"icon": "extension-icon.png",
"author": "adrianbonpin",
"categories": ["Productivity", "Developer Tools"],
"license": "MIT",
"commands": [
{
"name": "chat",
"title": "Chat with Lam",
"subtitle": "Lam Agent",
"description": "Ask Lam anything. Answers stream in as they are generated, your session history is kept, and Lam can search the web when it needs current information.",
"mode": "view"
},
{
"name": "snip",
"title": "Snip to Lam",
"subtitle": "Lam Agent",
"description": "Capture a region of the screen and start a new chat about it. The launcher window closes first so it cannot end up in the shot. Offered only when the model in preferences supports image input.",
"mode": "no-view"
},
{
"name": "sessions",
"title": "Chat Sessions",
"description": "Browse, reopen, and clean up your past conversations with Lam.",
"mode": "view"
},
{
"name": "models",
"title": "Ollama Models",
"subtitle": "Lam Agent",
"description": "Browse the models your Ollama host can reach, pick the one Lam should use, unload one that is holding memory, and pull or delete models on a server you run. A pick takes effect immediately; a pull keeps downloading until it finishes, so leave the launcher open.",
"mode": "view"
},
{
"name": "setup",
"title": "Set Up Lam Agent",
"description": "Check your Ollama connection, pick the model Lam should use, and tune how Lam answers.",
"mode": "view"
}
],
"preferences": [
{
"name": "apiKey",
"title": "Ollama API Key",
"description": "Your Ollama API key, created at ollama.com/settings/keys. Required to reach cloud models and the web search tools.",
"type": "password",
"required": true
},
{
"name": "model",
"title": "Model",
"description": "The model Lam should use, for example deepseek-v4.1-flash:cloud or gpt-oss:120b. Run \"Set Up Lam Agent\" to pick from the models your key can access.",
"type": "textfield",
"required": true
},
{
"name": "ollamaHost",
"title": "Ollama Host",
"description": "Base URL of the Ollama API. Leave this alone for Ollama Cloud, or point it at http://localhost:11434 to use a local Ollama server.",
"type": "textfield",
"required": false,
"default": "https://ollama.com"
},
{
"name": "systemPrompt",
"title": "System Prompt",
"description": "Extra instructions prepended to every conversation. Leave empty to use Lam's default prompt.",
"type": "textfield",
"required": false
},
{
"name": "location",
"title": "Location",
"description": "The place Lam should treat as yours, for example Cebu City, Philippines. Optional. Without it Lam falls back to your device timezone and locale, which are accurate to a region and not to a city, so anything that depends on exactly where you are (weather, opening hours) is worth filling in.",
"type": "textfield",
"required": false
},
{
"name": "ipGeolocation",
"title": "IP Geolocation",
"label": "Look up my city from my IP address",
"description": "Off by default. When this is on, and the Location preference above is empty, Lam sends your IP address to ipwho.is to work out roughly where you are. That is a third party learning approximately where you are, which is why it is opt-in, and why setting Location makes it unnecessary. It is coarser than a city: an IP address locates the point where traffic left your ISP, which can be hundreds of kilometres away.",
"type": "checkbox",
"required": false,
"default": false
},
{
"name": "webSearchEnabled",
"title": "Web Tools",
"label": "Let Lam search the web",
"description": "Let Lam search the web and fetch pages when a question needs up-to-date information.",
"type": "checkbox",
"required": false,
"default": true
},
{
"name": "thinking",
"title": "Reasoning Effort",
"description": "Ask supported models to reason before answering. Higher effort is slower but more accurate. Ignored by models that do not support it.",
"type": "dropdown",
"required": false,
"default": "off",
"data": [
{ "title": "Off", "value": "off" },
{ "title": "Low", "value": "low" },
{ "title": "Medium", "value": "medium" },
{ "title": "High", "value": "high" }
]
},
{
"name": "showToolCalls",
"title": "Show Tool Calls",
"label": "Show which tools Lam used",
"description": "List the tools Lam called under each answer, for example web_search or get_datetime.",
"type": "checkbox",
"required": false,
"default": true
},
{
"name": "showReasoning",
"title": "Show Reasoning",
"label": "Show the model's reasoning",
"description": "Include the model's thinking trace under each answer. Useful for seeing why a model answered the way it did, but it makes replies much longer.",
"type": "checkbox",
"required": false,
"default": true
},
{
"name": "resumeTimeout",
"title": "Start New Chat After",
"description": "When the command opens, resume the last conversation only if it was used recently. Past this much idle time it starts a fresh chat instead. The old conversation is never deleted. It stays in the sidebar.",
"type": "dropdown",
"required": false,
"default": "1h",
"data": [
{ "title": "Never (always reopen the last chat)", "value": "never" },
{ "title": "After 15 minutes", "value": "15m" },
{ "title": "After 1 hour", "value": "1h" },
{ "title": "After 6 hours", "value": "6h" },
{ "title": "After 1 day", "value": "1d" }
]
},
{
"name": "autoDeleteAfter",
"title": "Delete Old Chats After",
"description": "Permanently delete a conversation once you have not opened it for this long, along with any screenshots it captured. The check runs when a Lam command opens and after each answer, so conversations go when you next use Lam. Off by default: nothing is ever deleted.",
"type": "dropdown",
"required": false,
"default": "disabled",
"data": [
{ "title": "Disabled (keep conversations forever)", "value": "disabled" },
{ "title": "After 1 day", "value": "1d" },
{ "title": "After 7 days", "value": "7d" },
{ "title": "After 30 days", "value": "30d" },
{ "title": "After 90 days", "value": "90d" }
]
},
{
"name": "maxToolRounds",
"title": "Tool Call Limit",
"description": "How many rounds of tool calls Lam may make before it has to answer with what it has gathered. More rounds mean slower but more thorough answers. Unlimited removes the cap; a call that repeats itself with the same arguments three times ends the turn either way, so a stuck model cannot loop forever.",
"type": "dropdown",
"required": false,
"default": "8",
"data": [
{ "title": "4 rounds", "value": "4" },
{ "title": "8 rounds (default)", "value": "8" },
{ "title": "16 rounds", "value": "16" },
{ "title": "Unlimited (no cap)", "value": "unlimited" }
]
}
,
{
"name": "fileAccess",
"title": "File Access",
"label": "Let Lam read and change files",
"description": "Off by default. When this is on, Lam can list, search and read files under your home directory, and can create, change, move and delete files in Downloads, Documents/Lam Agent and its own folder. Every change is shown to you for approval first, credential stores are never readable, and anything Lam reads is sent to the model provider with the conversation.",
"type": "checkbox",
"required": false,
"default": false
},
{
"name": "readRoots",
"title": "Extra Readable Folders",
"description": "Additional folders Lam may read, one absolute path per line. Your home directory is always readable, except for credential stores. Useful for a project folder or an external drive.",
"type": "textfield",
"required": false
},
{
"name": "writeRoots",
"title": "Extra Writable Folders",
"description": "Additional folders Lam may change, one absolute path per line. Downloads and Documents/Lam Agent are always writable when File Access is on, and everything here is still approved change by change.",
"type": "textfield",
"required": false
}
],
"dependencies": {
"@vicinae/api": "^0.29.0",
"zod": "^4.4.3"
},
"devDependencies": {
"@eslint/js": "^9.36.0",
"@types/node": "22.13.10",
"@types/react": "19.1.17",
"eslint": "^9.22.0",
"eslint-config-prettier": "^10.1.8",
"globals": "^16.4.0",
"prettier": "^3.5.3",
"react": "19.1.1",
"typescript": "^5.8.2",
"typescript-eslint": "^8.45.0",
"vitest": "^4.1.5"
},
"scripts": {
"dev": "vici develop",
"build": "vici build",
"lint": "vici lint",
"lint:code": "eslint .",
"format": "prettier --write \"src/**/*.{ts,tsx}\"",
"typecheck": "tsc --noEmit",
"test": "vitest run",
"test:watch": "vitest"
}
}