Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,16 @@
- Added clean-tree, `origin/master`, tag/version, artifact identity, size, and payload-hygiene checks.
- Retired the unused duplicate Python `core/` package; its maintained workflow-migration behavior already lives in `src/utils/migration/mdWorkflow.ts` with Jest coverage.

### Secure AI providers and MCP

- Switched the Python AI bridge to a module entry point with the OpenAI Responses API and
Ollama generate API, using fake-HTTP coverage rather than live provider requests.
- Moved OpenAI credentials out of configuration and into VS Code SecretStorage with explicit set
and clear commands.
- Added cancellation, provider and subprocess timeouts, bounded output, and secret-safe errors.
- Routed and validated all five tools declared by the dependency-free MCP server while preserving
JSON-RPC request IDs and normalizing missing optional dependencies and tool failures.

## [3.0.6] - 2026-03-05
## [3.0.7] - 2026-03-05

Expand Down Expand Up @@ -440,7 +450,7 @@ Phase 5 remaining tasks:
- VSCode settings for AI:
- `openqc.ai.enabled` - Enable/disable AI features
- `openqc.ai.provider` - Select provider (openai/ollama)
- `openqc.ai.apiKey` - OpenAI API key
- OpenAI API key setting (historical; removed above in favor of SecretStorage)
- `openqc.ai.model` - Model name
- `openqc.ai.ollamaUrl` - Ollama server URL
- `openqc.ai.maxTokens` - Maximum response tokens
Expand Down
3 changes: 3 additions & 0 deletions MEMORY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Agent Memory

- Session notes live in [docs/agent-memory.md](docs/agent-memory.md).
19 changes: 17 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,21 @@ OpenQC works out of the box, but you can customize it:
}
```

### Secure AI providers

OpenQC can use the OpenAI Responses API or a local Ollama server for input optimization,
generation, explanation, and debugging. Enable `openqc.ai.enabled`, select the provider and
model, then run **OpenQC: Set OpenAI API Key** when using OpenAI. The credential is stored in
VS Code SecretStorage and is never written to user or workspace settings; use **OpenQC: Clear
OpenAI API Key** to remove it. Provider calls are cancellable and bounded by the configured
timeout, token limit, and output-character limit.

From a source checkout, the dependency-free MCP entry point is
`PYTHONPATH=python python -m openqc.mcp_server`. It exposes five tools for
structure parsing, output parsing, backend checks, supercell generation, and dataset summaries.
Native paths continue to work when optional scientific packages are absent; tools that require a
missing package return a structured JSON-RPC error without terminating the server.

---

## 💡 Use Cases
Expand Down Expand Up @@ -253,8 +268,8 @@ OpenQC works out of the box, but you can customize it:
- [ ] Community examples for common calculation workflows

### Long Term (v3.0)
- [ ] AI-powered parameter optimization
- [ ] Natural language input generation
- [x] AI-powered parameter optimization with OpenAI and Ollama
- [x] Natural language input generation
- [ ] Workflow automation
- [ ] Demand-proven ecosystem integrations from the [roadmap](docs/project/PLAN.md)

Expand Down
15 changes: 15 additions & 0 deletions docs/agent-memory.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Agent Memory

## 2026-07-16 - Issue #237

- The production AI bridge must launch `openqc.ai.client` with `python -m`; eager imports from
`openqc.ai.__init__` trigger a `runpy` warning, so client exports are lazy.
- OpenAI uses the Responses API and receives its credential only from VS Code SecretStorage.
Fake local HTTP servers cover provider behavior; tests must never send live provider requests.
- The dependency-free MCP server declares five tools. Keep the tool schemas, handler routing,
JSON-RPC validation, request IDs, and normalized optional-dependency errors in one module.
- The PR contract recognizes test evidence only when the body contains `Tests`, `Test Plan`, or
`TDD Evidence`; a generic `Validation` heading does not satisfy the check.
- `make lint` is currently blocked by 544 pre-existing Ruff errors under `core/`. `make test`
reaches a missing `pytest` executable and a nonexistent `core/tests/unit` path after the Jest
unit suite passes; use the maintained root Python tests plus npm/Jest gates for this slice.
49 changes: 42 additions & 7 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,14 @@
"onCommand:openqc.validate",
"onView:openqc-sidebar",
"onCommand:openqc.previewInput",
"onCommand:openqc.convertFormat"
"onCommand:openqc.convertFormat",
"onCommand:openqc.aiOptimizeInput",
"onCommand:openqc.aiGenerateInput",
"onCommand:openqc.aiExplainParameters",
"onCommand:openqc.aiDebugCalculation",
"onCommand:openqc.aiSettings",
"onCommand:openqc.aiSetApiKey",
"onCommand:openqc.aiClearApiKey"
],
"main": "./out/extension.js",
"extensionKind": [
Expand Down Expand Up @@ -610,6 +617,18 @@
"category": "AI",
"icon": "$(gear)"
},
{
"command": "openqc.aiSetApiKey",
"title": "OpenQC: Set OpenAI API Key",
"category": "AI",
"icon": "$(key)"
},
{
"command": "openqc.aiClearApiKey",
"title": "OpenQC: Clear OpenAI API Key",
"category": "AI",
"icon": "$(trash)"
},
{
"command": "openqc.showConverterPanel",
"title": "Show ASE Converter",
Expand Down Expand Up @@ -1379,15 +1398,15 @@
"default": "ollama",
"description": "AI provider (OpenAI or Ollama)"
},
"openqc.ai.apiKey": {
"type": "string",
"default": "",
"description": "OpenAI API key (only used with OpenAI provider)"
},
"openqc.ai.model": {
"type": "string",
"default": "llama2",
"description": "AI model name (gpt-4 for OpenAI, llama2 for Ollama)"
"description": "AI model name for the selected provider"
},
"openqc.ai.openaiBaseUrl": {
"type": "string",
"default": "https://api.openai.com/v1",
"description": "OpenAI-compatible API base URL"
},
"openqc.ai.ollamaUrl": {
"type": "string",
Expand All @@ -1397,8 +1416,24 @@
"openqc.ai.maxTokens": {
"type": "number",
"default": 2048,
"minimum": 1,
"maximum": 131072,
"description": "Maximum tokens in AI response"
},
"openqc.ai.maxOutputChars": {
"type": "number",
"default": 100000,
"minimum": 256,
"maximum": 1000000,
"description": "Maximum AI response characters accepted by the extension"
},
"openqc.ai.timeoutSeconds": {
"type": "number",
"default": 120,
"exclusiveMinimum": 0,
"maximum": 600,
"description": "Timeout for AI provider and bridge requests"
},
"openqc.ai.temperature": {
"type": "number",
"default": 0.7,
Expand Down
14 changes: 11 additions & 3 deletions python/openqc/ai/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,16 @@
generation, explanation, and debugging.
"""

from .client import AIClient, AIRequest, AIResponse
from .prompts import PromptTemplates
from .parser import ResponseParser
from .prompts import PromptTemplates

__all__ = ["AIClient", "AIRequest", "AIResponse", "PromptTemplates", "ResponseParser"]


def __getattr__(name):
"""Load client types lazily so ``python -m openqc.ai.client`` stays warning-free."""
if name in {"AIClient", "AIRequest", "AIResponse"}:
from . import client

__all__ = ['AIClient', 'AIRequest', 'AIResponse', 'PromptTemplates', 'ResponseParser']
return getattr(client, name)
raise AttributeError(name)
Loading
Loading