Skip to content
Open
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: 6 additions & 6 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
# LLM provider — set one of: openai, anthropic, google
CONCLAVE_LLM_PROVIDER=openai
CONCLAVE_OPENAI_API_KEY=
CONCLAVE_OPENAI_MODEL=gpt-4o
CONCLAVE_ANTHROPIC_API_KEY=
CONCLAVE_GOOGLE_API_KEY=
# NearAI API — all models served via NearAI confidential compute
CONCLAVE_NEARAI_API_KEY=
CONCLAVE_DEFAULT_MODEL=deepseek-ai/DeepSeek-V3.1

# Supabase auth — Project Settings → API in your Supabase dashboard
# JWT validation uses JWKS (ES256/ECC P-256) — no shared secret needed
Expand All @@ -14,3 +11,6 @@ CONCLAVE_SUPABASE_ANON_KEY=
LANGCHAIN_TRACING_V2=true
LANGCHAIN_API_KEY=
LANGCHAIN_PROJECT=conclave-eval

# Per-skill model config lives in skills/<skill-name>/.env
# See skills/hackathon_novelty/.env.example for an example
5 changes: 4 additions & 1 deletion api/routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,10 @@ def get_results(submission_id: str, request: Request):
if role == "user":
if submission_id not in token_info["submission_ids"]:
raise HTTPException(status_code=403, detail="Access denied: submission not owned by this token")
return instance_results[submission_id]
# Participant view: filtered to skill-declared user_output_keys
card = _skill_router.get_card(_instances[instance_id]["skill_name"])
result = instance_results[submission_id]
return {k: result[k] for k in card.user_output_keys if k in result}

# admin: unrestricted access within the instance
return instance_results[submission_id]
Expand Down
45 changes: 18 additions & 27 deletions config.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
from __future__ import annotations
from pydantic_settings import BaseSettings
from typing import Literal


class Settings(BaseSettings):
llm_provider: Literal["openai", "anthropic", "google", "nearai"] = "openai"
openai_api_key: str = ""
openai_model: str = "gpt-4o"
anthropic_api_key: str = ""
google_api_key: str = ""
# NearAI API — all models served via NearAI confidential compute
nearai_api_key: str = ""
nearai_model: str = "deepseek-ai/DeepSeek-V3.1"
nearai_base_url: str = "https://cloud-api.near.ai/v1"
default_model: str = "deepseek-ai/DeepSeek-V3.1"

# Embedding (unchanged)
embedding_model: str = "all-MiniLM-L6-v2"

# Supabase auth (optional — if unset, /auth/* endpoints return 503 and /register is the fallback)
Expand All @@ -22,23 +21,15 @@ class Settings(BaseSettings):
settings = Settings()


def get_llm():
"""Return the configured LangChain chat model."""
if settings.llm_provider == "openai":
from langchain_openai import ChatOpenAI
return ChatOpenAI(model=settings.openai_model, api_key=settings.openai_api_key)
elif settings.llm_provider == "anthropic":
from langchain_anthropic import ChatAnthropic
return ChatAnthropic(model="claude-sonnet-4-6", api_key=settings.anthropic_api_key)
elif settings.llm_provider == "google":
from langchain_google_genai import ChatGoogleGenerativeAI
return ChatGoogleGenerativeAI(model="gemini-2.0-flash", google_api_key=settings.google_api_key)
elif settings.llm_provider == "nearai":
from langchain_openai import ChatOpenAI
return ChatOpenAI(
model=settings.nearai_model,
api_key=settings.nearai_api_key,
base_url="https://cloud-api.near.ai/v1",
)
else:
raise ValueError(f"Unsupported LLM provider: {settings.llm_provider}")
def get_llm(model: str | None = None):
"""Return the configured LangChain chat model via NearAI.

model: specific model ID to use. Falls back to settings.default_model if None.
Skills declare their own per-node models in their own config.py.
"""
from langchain_openai import ChatOpenAI
return ChatOpenAI(
model=model or settings.default_model,
api_key=settings.nearai_api_key,
base_url=settings.nearai_base_url,
)
2 changes: 2 additions & 0 deletions core/skill_card.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ class SkillCard:
run: Callable # the run_skill() entry point
input_model: Type[BaseModel] # Pydantic model for this skill's inputs
output_keys: set # allowed output keys (mirrors ALLOWED_OUTPUT_KEYS)
user_output_keys: set = field(default_factory=set) # keys visible to user role (subset of output_keys)
config: dict = field(default_factory=dict) # skill-specific config params
trigger_modes: list = field(default_factory=list) # supported trigger declarations
roles: dict = field(default_factory=dict) # admin + user role declarations
Expand All @@ -44,6 +45,7 @@ def metadata(self) -> dict:
"version": self.version,
"input_schema": self.input_model.model_json_schema(),
"output_keys": sorted(self.output_keys),
"user_output_keys": sorted(self.user_output_keys),
"config": self.config,
"trigger_modes": self.trigger_modes,
"roles": self.roles,
Expand Down
Loading
Loading