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
149 changes: 149 additions & 0 deletions opencode.jsonc
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
{
"$schema": "https://opencode.ai/config.json",
"plugin": [
"@openontology/opencode-palantir@0.1.5"
],
"model": "openai/gpt-5.3-codex",
"tools": {
"palantir-mcp_*": true
},
"mcp": {
"palantir-mcp": {
"type": "local",
"command": [
"npx",
"-y",
"palantir-mcp",
"--foundry-api-url",
"{env:FOUNDRY_URL}"
],
"environment": {
"FOUNDRY_TOKEN": "{env:FOUNDRY_TOKEN}"
}
}
},
"agent": {
"foundry-librarian": {
"mode": "subagent",
"hidden": false,
"description": "Foundry exploration and context gathering (parallel-friendly) | Generated by opencode-palantir /setup-palantir-mcp. Profile: unknown. Edit palantir-mcp_* tool flags below to reject tools.",
"prompt": "You are the Foundry librarian.\n\n- Focus on exploration and context gathering.\n- Split independent exploration tasks and run them in parallel when possible.\n- Return compact summaries and cite the tool calls you ran.\n- Avoid dumping massive schemas unless explicitly asked.",
"tools": {
"get_doc_page": true,
"list_all_docs": true,
"palantir-mcp_aggregate_ontology_objects": false,
"palantir-mcp_build_datasets": false,
"palantir-mcp_clone_code_repository_locally": false,
"palantir-mcp_close_foundry_branch": false,
"palantir-mcp_close_foundry_proposal": false,
"palantir-mcp_connect_to_dev_console_app": false,
"palantir-mcp_convert_to_osdk_react": false,
"palantir-mcp_create_and_write_to_foundry_dataset": false,
"palantir-mcp_create_code_repository_pull_request": false,
"palantir-mcp_create_foundry_branch": false,
"palantir-mcp_create_foundry_proposal": false,
"palantir-mcp_create_foundry_rest_api_data_source": false,
"palantir-mcp_create_foundry_rest_api_data_source_webhook": false,
"palantir-mcp_create_or_update_foundry_link_type": false,
"palantir-mcp_create_or_update_foundry_object_type": false,
"palantir-mcp_create_python_transforms_code_repository": false,
"palantir-mcp_delete_foundry_link_type": false,
"palantir-mcp_delete_foundry_object_type": false,
"palantir-mcp_generate_new_ontology_sdk_version": false,
"palantir-mcp_get_build_status": true,
"palantir-mcp_get_compute_modules_documentation": true,
"palantir-mcp_get_custom_widget_documentation": true,
"palantir-mcp_get_foundry_dataset_schema": true,
"palantir-mcp_get_foundry_ontology_rid": true,
"palantir-mcp_get_job_status": true,
"palantir-mcp_get_ml_documentation": true,
"palantir-mcp_get_ontology_sdk_context": true,
"palantir-mcp_get_ontology_sdk_examples": true,
"palantir-mcp_get_or_create_network_egress_policy": true,
"palantir-mcp_get_platform_sdk_api_reference": true,
"palantir-mcp_get_project_imports": true,
"palantir-mcp_get_python_transforms_documentation": true,
"palantir-mcp_get_repository_context": true,
"palantir-mcp_get_resource_graph": true,
"palantir-mcp_get_typescript_v1_functions_documentation": true,
"palantir-mcp_get_typescript_v2_functions_documentation": true,
"palantir-mcp_install_sdk_package": false,
"palantir-mcp_list_platform_sdk_apis": true,
"palantir-mcp_list_resources_in_foundry_folder": true,
"palantir-mcp_query_ontology_objects": true,
"palantir-mcp_run_sql_query_on_foundry_dataset": false,
"palantir-mcp_search_dataset_builds": true,
"palantir-mcp_search_foundry_documentation": true,
"palantir-mcp_search_foundry_functions": true,
"palantir-mcp_search_foundry_ontology": true,
"palantir-mcp_view_foundry_action_type": false,
"palantir-mcp_view_foundry_branch": false,
"palantir-mcp_view_foundry_link_type": false,
"palantir-mcp_view_foundry_object_type": false,
"palantir-mcp_view_foundry_proposal": false,
"palantir-mcp_view_osdk_definition": false
}
},
"foundry": {
"mode": "all",
"hidden": false,
"description": "Foundry execution agent (uses only enabled palantir-mcp tools) | Generated by opencode-palantir /setup-palantir-mcp. Profile: unknown. Edit palantir-mcp_* tool flags below to reject tools.",
"prompt": "You are the Foundry execution agent.\n\n- Use only enabled palantir-mcp tools.\n- Prefer working from summaries produced by @foundry-librarian.\n- Keep operations focused and deterministic.",
"tools": {
"get_doc_page": false,
"list_all_docs": false,
"palantir-mcp_aggregate_ontology_objects": false,
"palantir-mcp_build_datasets": false,
"palantir-mcp_clone_code_repository_locally": false,
"palantir-mcp_close_foundry_branch": false,
"palantir-mcp_close_foundry_proposal": false,
"palantir-mcp_connect_to_dev_console_app": true,
"palantir-mcp_convert_to_osdk_react": false,
"palantir-mcp_create_and_write_to_foundry_dataset": false,
"palantir-mcp_create_code_repository_pull_request": false,
"palantir-mcp_create_foundry_branch": false,
"palantir-mcp_create_foundry_proposal": false,
"palantir-mcp_create_foundry_rest_api_data_source": true,
"palantir-mcp_create_foundry_rest_api_data_source_webhook": true,
"palantir-mcp_create_or_update_foundry_link_type": false,
"palantir-mcp_create_or_update_foundry_object_type": false,
"palantir-mcp_create_python_transforms_code_repository": false,
"palantir-mcp_delete_foundry_link_type": false,
"palantir-mcp_delete_foundry_object_type": false,
"palantir-mcp_generate_new_ontology_sdk_version": false,
"palantir-mcp_get_build_status": true,
"palantir-mcp_get_compute_modules_documentation": true,
"palantir-mcp_get_custom_widget_documentation": true,
"palantir-mcp_get_foundry_dataset_schema": true,
"palantir-mcp_get_foundry_ontology_rid": true,
"palantir-mcp_get_job_status": true,
"palantir-mcp_get_ml_documentation": true,
"palantir-mcp_get_ontology_sdk_context": true,
"palantir-mcp_get_ontology_sdk_examples": true,
"palantir-mcp_get_or_create_network_egress_policy": true,
"palantir-mcp_get_platform_sdk_api_reference": true,
"palantir-mcp_get_project_imports": true,
"palantir-mcp_get_python_transforms_documentation": true,
"palantir-mcp_get_repository_context": true,
"palantir-mcp_get_resource_graph": true,
"palantir-mcp_get_typescript_v1_functions_documentation": true,
"palantir-mcp_get_typescript_v2_functions_documentation": true,
"palantir-mcp_install_sdk_package": false,
"palantir-mcp_list_platform_sdk_apis": true,
"palantir-mcp_list_resources_in_foundry_folder": true,
"palantir-mcp_query_ontology_objects": true,
"palantir-mcp_run_sql_query_on_foundry_dataset": false,
"palantir-mcp_search_dataset_builds": true,
"palantir-mcp_search_foundry_documentation": true,
"palantir-mcp_search_foundry_functions": true,
"palantir-mcp_search_foundry_ontology": true,
"palantir-mcp_view_foundry_action_type": false,
"palantir-mcp_view_foundry_branch": false,
"palantir-mcp_view_foundry_link_type": false,
"palantir-mcp_view_foundry_object_type": false,
"palantir-mcp_view_foundry_proposal": false,
"palantir-mcp_view_osdk_definition": false
}
}
}
}
68 changes: 65 additions & 3 deletions src/common/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,64 @@ def _load_extra_headers(env: EnvironmentSettings) -> dict[str, str]:
return headers


def _load_source_credentials() -> dict[str, object]:
"""Load compute module source credentials JSON, if present."""

path = os.environ.get("SOURCE_CREDENTIALS")
if not path:
return {}

try:
with open(path, "r", encoding="utf-8") as handle:
data = json.load(handle)
except FileNotFoundError:
return {}
except json.JSONDecodeError as exc:
raise RuntimeError(
"Invalid JSON in SOURCE_CREDENTIALS file. Check compute module Source configuration."
) from exc

if not isinstance(data, dict):
return {}

return data


def _get_openrouter_api_key_from_sources() -> str | None:
"""Try to resolve OpenRouter API key from compute module Sources."""

credentials = _load_source_credentials()

preferred_source = os.environ.get("OPENROUTER_SOURCE_API_NAME") or "OpenRouterAPIService"
preferred_field = os.environ.get("OPENROUTER_SOURCE_SECRET_FIELD") or "additionalSecretOpenRouterApiKey"

keys = [
preferred_field,
"additionalSecretOpenRouterApiKey",
"apiKey",
"OPENROUTER_API_KEY",
]

source_names: list[str] = []
if preferred_source in credentials:
source_names.append(preferred_source)
source_names.extend([name for name in sorted(credentials.keys()) if name != preferred_source])

for source_name in source_names:
entry = credentials.get(source_name)
if not isinstance(entry, dict):
continue
for field in keys:
value = entry.get(field)
if isinstance(value, str):
value = value.strip()
if value:
os.environ.setdefault("OPENROUTER_API_KEY", value)
return value

return None


def load_llm_config() -> LLMConfig:
"""Load LM configuration from environment variables."""

Expand All @@ -92,8 +150,12 @@ def load_llm_config() -> LLMConfig:
)

# OpenRouter provider (default)
if not env.openrouter_api_key:
raise RuntimeError("No API key found. Set OPENROUTER_API_KEY or use DSPY_PROVIDER=local.")
openrouter_api_key = env.openrouter_api_key or _get_openrouter_api_key_from_sources()
if not openrouter_api_key:
raise RuntimeError(
"No API key found. Set OPENROUTER_API_KEY, or bind a compute module Source containing "
"additionalSecretOpenRouterApiKey, or use DSPY_PROVIDER=local."
)

model_name = env.model_name or DEFAULT_MODEL
# Ensure model has openrouter/ prefix for litellm provider routing
Expand All @@ -102,7 +164,7 @@ def load_llm_config() -> LLMConfig:

return LLMConfig(
model=model_name,
api_key=env.openrouter_api_key,
api_key=openrouter_api_key,
api_base=DEFAULT_OPENROUTER_BASE,
headers=_load_extra_headers(env),
)
Expand Down