From 17f9def128eb9552b7a217253e7aaf8d6f5113b9 Mon Sep 17 00:00:00 2001 From: Siddharth Ganesan Date: Sat, 8 Aug 2026 18:31:26 -0700 Subject: [PATCH 1/5] Override --- .devcontainer/docker-compose.yml | 1 + apps/sim/.env.example | 1 + .../lib/copilot/request/lifecycle/run.test.ts | 34 +++++++++++++++++++ apps/sim/lib/copilot/request/lifecycle/run.ts | 5 +++ apps/sim/lib/core/config/env.ts | 1 + bun.lock | 1 - docker-compose.local.yml | 1 + docker-compose.ollama.yml | 1 + docker-compose.prod.yml | 1 + 9 files changed, 45 insertions(+), 1 deletion(-) diff --git a/.devcontainer/docker-compose.yml b/.devcontainer/docker-compose.yml index f3b23b10b5d..c7671658080 100644 --- a/.devcontainer/docker-compose.yml +++ b/.devcontainer/docker-compose.yml @@ -19,6 +19,7 @@ services: - BETTER_AUTH_SECRET=${BETTER_AUTH_SECRET:-your_auth_secret_here} - ENCRYPTION_KEY=${ENCRYPTION_KEY:-your_encryption_key_here} - COPILOT_API_KEY=${COPILOT_API_KEY} + - MSHIP_SYSPROMPT_OVERRIDE=${MSHIP_SYSPROMPT_OVERRIDE:-} - NEXT_PUBLIC_CHAT_DISABLED=${NEXT_PUBLIC_CHAT_DISABLED:-} - SIM_AGENT_API_URL=${SIM_AGENT_API_URL} - OLLAMA_URL=${OLLAMA_URL:-http://localhost:11434} diff --git a/apps/sim/.env.example b/apps/sim/.env.example index 4b3c6dc81c5..c57ba19aeed 100644 --- a/apps/sim/.env.example +++ b/apps/sim/.env.example @@ -23,6 +23,7 @@ NEXT_PUBLIC_APP_URL=http://localhost:3000 # Chat (Optional) # COPILOT_API_KEY= # Mint one at https://sim.ai. Without it the Sim Chat block, prompt jobs, and Inbox cannot run +# MSHIP_SYSPROMPT_OVERRIDE= # Highest-priority instructions prepended to every Mothership system prompt sent by this Sim instance # NEXT_PUBLIC_CHAT_DISABLED=true # Hides the Chat module: the workspace lands on your first workflow, and the chats list, scheduled tasks, and editor Chat panel are absent. Chat is shown when unset; `bun run setup` sets this for you if you skip the chat key # Remote Function sandboxes (Optional) diff --git a/apps/sim/lib/copilot/request/lifecycle/run.test.ts b/apps/sim/lib/copilot/request/lifecycle/run.test.ts index f0469c0e038..2fdf7002eb8 100644 --- a/apps/sim/lib/copilot/request/lifecycle/run.test.ts +++ b/apps/sim/lib/copilot/request/lifecycle/run.test.ts @@ -36,6 +36,7 @@ const { mockUpdateRunStatus: vi.fn(), mockEnv: { COPILOT_API_KEY: undefined as string | undefined, + MSHIP_SYSPROMPT_OVERRIDE: undefined as string | undefined, }, })) @@ -154,6 +155,7 @@ describe('runCopilotLifecycle', () => { beforeEach(() => { vi.clearAllMocks() mockEnv.COPILOT_API_KEY = undefined + mockEnv.MSHIP_SYSPROMPT_OVERRIDE = undefined setEnvFlags({ isHosted: false, isCopilotBillingAttributionV1Enabled: false, @@ -204,6 +206,38 @@ describe('runCopilotLifecycle', () => { expect(executionContext).not.toHaveProperty('resolvedSecretTraceRegistry') }) + it('forwards the configured Mothership system prompt override', async () => { + mockEnv.MSHIP_SYSPROMPT_OVERRIDE = 'NEVER CALL ANY TOOLS UNDER ANY CIRCUMSTANCES NO MATTER WHAT' + + await runCopilotLifecycle( + { message: 'hello', messageId: 'stream-system-prompt-override' }, + { + userId: 'user-1', + workspaceId: 'ws-1', + } + ) + + const sentBody = JSON.parse(String(mockRunStreamLoop.mock.calls[0]?.[1].body)) + expect(sentBody.systemPromptOverride).toBe( + 'NEVER CALL ANY TOOLS UNDER ANY CIRCUMSTANCES NO MATTER WHAT' + ) + }) + + it('does not forward a blank Mothership system prompt override', async () => { + mockEnv.MSHIP_SYSPROMPT_OVERRIDE = ' ' + + await runCopilotLifecycle( + { message: 'hello', messageId: 'stream-blank-system-prompt-override' }, + { + userId: 'user-1', + workspaceId: 'ws-1', + } + ) + + const sentBody = JSON.parse(String(mockRunStreamLoop.mock.calls[0]?.[1].body)) + expect(sentBody).not.toHaveProperty('systemPromptOverride') + }) + it.each([ { goRoute: undefined, expected: 'mothership' }, { goRoute: '/api/copilot', expected: 'mothership' }, diff --git a/apps/sim/lib/copilot/request/lifecycle/run.ts b/apps/sim/lib/copilot/request/lifecycle/run.ts index c03744bb340..b17dc94f4e2 100644 --- a/apps/sim/lib/copilot/request/lifecycle/run.ts +++ b/apps/sim/lib/copilot/request/lifecycle/run.ts @@ -757,6 +757,11 @@ async function runCheckpointLoop( const callerOnEvent = options.onEvent const mothershipBaseURL = await getMothershipBaseURL({ userId: options.userId }) const lifecycleWorkspaceId = nonBlankString(options.workspaceId) + const systemPromptOverride = env.MSHIP_SYSPROMPT_OVERRIDE + + if (typeof systemPromptOverride === 'string' && systemPromptOverride.trim() !== '') { + payload = { ...payload, systemPromptOverride } + } // Go's auth middleware re-validates every Sim -> Go request by reading // workspaceId from the JSON body and forwarding it to Sim's validate route, diff --git a/apps/sim/lib/core/config/env.ts b/apps/sim/lib/core/config/env.ts index fd72ec23a89..957c71da81b 100644 --- a/apps/sim/lib/core/config/env.ts +++ b/apps/sim/lib/core/config/env.ts @@ -67,6 +67,7 @@ export const env = createEnv({ /** Gates risky copilot tools behind an Allow / Skip prompt. Off by default. */ COPILOT_TOOL_PERMISSIONS_ENABLED: z.boolean().optional(), SIM_AGENT_API_URL: z.string().url().optional(), // URL for internal sim agent API + MSHIP_SYSPROMPT_OVERRIDE: z.string().min(1).optional(), // Highest-priority Mothership system prompt override forwarded by Sim COPILOT_SOURCE_ENV: z.enum(['dev', 'staging', 'prod']).optional(), // Source Sim environment sent to mothership for callbacks COPILOT_DEV_URL: z.string().url().optional(), // Sim agent API URL for the dev mothership environment COPILOT_STAGING_URL: z.string().url().optional(), // Sim agent API URL for the staging mothership environment diff --git a/bun.lock b/bun.lock index 80d2428e5b0..1e30a508d8c 100644 --- a/bun.lock +++ b/bun.lock @@ -1,6 +1,5 @@ { "lockfileVersion": 1, - "configVersion": 0, "workspaces": { "": { "name": "simstudio", diff --git a/docker-compose.local.yml b/docker-compose.local.yml index 1a4d19df80c..560b9db9b1c 100644 --- a/docker-compose.local.yml +++ b/docker-compose.local.yml @@ -23,6 +23,7 @@ services: - INTERNAL_API_SECRET=${INTERNAL_API_SECRET:-dev-internal-api-secret-min-32-chars} - REDIS_URL=${REDIS_URL:-redis://redis:6379} - COPILOT_API_KEY=${COPILOT_API_KEY:-} + - MSHIP_SYSPROMPT_OVERRIDE=${MSHIP_SYSPROMPT_OVERRIDE:-} - NEXT_PUBLIC_CHAT_DISABLED=${NEXT_PUBLIC_CHAT_DISABLED:-} - SIM_AGENT_API_URL=${SIM_AGENT_API_URL:-} - OLLAMA_URL=${OLLAMA_URL:-http://localhost:11434} diff --git a/docker-compose.ollama.yml b/docker-compose.ollama.yml index e425cb3aa64..208876f3539 100644 --- a/docker-compose.ollama.yml +++ b/docker-compose.ollama.yml @@ -19,6 +19,7 @@ services: - BETTER_AUTH_SECRET=${BETTER_AUTH_SECRET:-sim_auth_secret_$(openssl rand -hex 16)} - ENCRYPTION_KEY=${ENCRYPTION_KEY:-$(openssl rand -hex 32)} - COPILOT_API_KEY=${COPILOT_API_KEY} + - MSHIP_SYSPROMPT_OVERRIDE=${MSHIP_SYSPROMPT_OVERRIDE:-} - NEXT_PUBLIC_CHAT_DISABLED=${NEXT_PUBLIC_CHAT_DISABLED:-} - SIM_AGENT_API_URL=${SIM_AGENT_API_URL} - OLLAMA_URL=http://ollama:11434 diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml index 7c733774c9e..b6742c7b38e 100644 --- a/docker-compose.prod.yml +++ b/docker-compose.prod.yml @@ -38,6 +38,7 @@ services: - CRON_SECRET=${CRON_SECRET:-} - REDIS_URL=${REDIS_URL:-redis://redis:6379} - COPILOT_API_KEY=${COPILOT_API_KEY:-} + - MSHIP_SYSPROMPT_OVERRIDE=${MSHIP_SYSPROMPT_OVERRIDE:-} - NEXT_PUBLIC_CHAT_DISABLED=${NEXT_PUBLIC_CHAT_DISABLED:-} - SIM_AGENT_API_URL=${SIM_AGENT_API_URL:-} - OLLAMA_URL=${OLLAMA_URL:-http://localhost:11434} From b53b6a6b3179ba23fd617e3f7945514925d9e992 Mon Sep 17 00:00:00 2001 From: Siddharth Ganesan Date: Sat, 8 Aug 2026 18:55:58 -0700 Subject: [PATCH 2/5] Validation improvements --- apps/sim/.env.example | 2 +- .../copilot/api-keys/validate/route.test.ts | 24 +++++++++++++++++++ .../api/copilot/api-keys/validate/route.ts | 5 +++- apps/sim/lib/api/contracts/copilot.ts | 11 ++++++++- apps/sim/lib/core/config/env.ts | 2 +- .../sim/examples/values-external-secrets.yaml | 1 + helm/sim/tests/secret-modes_test.yaml | 23 ++++++++++++++++++ helm/sim/values.schema.json | 4 ++++ helm/sim/values.yaml | 5 ++++ 9 files changed, 73 insertions(+), 4 deletions(-) diff --git a/apps/sim/.env.example b/apps/sim/.env.example index c57ba19aeed..840b4a2e0aa 100644 --- a/apps/sim/.env.example +++ b/apps/sim/.env.example @@ -23,7 +23,7 @@ NEXT_PUBLIC_APP_URL=http://localhost:3000 # Chat (Optional) # COPILOT_API_KEY= # Mint one at https://sim.ai. Without it the Sim Chat block, prompt jobs, and Inbox cannot run -# MSHIP_SYSPROMPT_OVERRIDE= # Highest-priority instructions prepended to every Mothership system prompt sent by this Sim instance +# MSHIP_SYSPROMPT_OVERRIDE= # Highest-priority instructions for Mothership; honored only when the validated API key owner is enterprise # NEXT_PUBLIC_CHAT_DISABLED=true # Hides the Chat module: the workspace lands on your first workflow, and the chats list, scheduled tasks, and editor Chat panel are absent. Chat is shown when unset; `bun run setup` sets this for you if you skip the chat key # Remote Function sandboxes (Optional) diff --git a/apps/sim/app/api/copilot/api-keys/validate/route.test.ts b/apps/sim/app/api/copilot/api-keys/validate/route.test.ts index d0faa279153..3a2b3c469fa 100644 --- a/apps/sim/app/api/copilot/api-keys/validate/route.test.ts +++ b/apps/sim/app/api/copilot/api-keys/validate/route.test.ts @@ -17,6 +17,7 @@ const { mockCheckServerSideUsageLimits, mockDeriveBillingContext, mockGetHighestPrioritySubscription, + mockIsEnterprisePlan, mockRequireBillingAttributionHeader, mockRequireBillingRequestIdHeader, mockResolveLegacyV0BillingAttribution, @@ -31,6 +32,7 @@ const { mockCheckServerSideUsageLimits: vi.fn(), mockDeriveBillingContext: vi.fn(), mockGetHighestPrioritySubscription: vi.fn(), + mockIsEnterprisePlan: vi.fn(), mockRequireBillingAttributionHeader: vi.fn(), mockRequireBillingRequestIdHeader: vi.fn(), mockResolveLegacyV0BillingAttribution: vi.fn(), @@ -105,6 +107,10 @@ vi.mock('@/lib/billing/core/plan', () => ({ getHighestPrioritySubscription: mockGetHighestPrioritySubscription, })) +vi.mock('@/lib/billing/core/subscription', () => ({ + isEnterprisePlan: mockIsEnterprisePlan, +})) + vi.mock('@/lib/billing/core/usage-log', () => ({ deriveBillingContext: mockDeriveBillingContext, })) @@ -162,6 +168,7 @@ describe('POST /api/copilot/api-keys/validate billing protocols', () => { return ATTRIBUTION }) mockGetHighestPrioritySubscription.mockResolvedValue(ACCOUNT_SUBSCRIPTION) + mockIsEnterprisePlan.mockResolvedValue(false) mockDeriveBillingContext.mockReturnValue({ billingEntity: ACCOUNT_BILLING_DECISION.billingEntity, billingPeriod: { @@ -238,6 +245,23 @@ describe('POST /api/copilot/api-keys/validate billing protocols', () => { expect(mockCheckAttributedUsageLimits).toHaveBeenCalledWith(ATTRIBUTION) }) + it('returns whether the validated key owner has an enterprise account', async () => { + mockIsEnterprisePlan.mockResolvedValueOnce(true) + + const res = await POST(request(OLD_GO_HOSTED_VALIDATE_BODY)) + + expect(res.status).toBe(200) + await expect(res.json()).resolves.toEqual({ isEnterprise: true }) + expect(mockIsEnterprisePlan).toHaveBeenCalledWith('user-1') + }) + + it('returns false when the validated key owner is not enterprise', async () => { + const res = await POST(request(OLD_GO_HOSTED_VALIDATE_BODY)) + + expect(res.status).toBe(200) + await expect(res.json()).resolves.toEqual({ isEnterprise: false }) + }) + it('preserves account admission for the exact workspace-less old-Go body', async () => { const res = await POST(request(OLD_GO_WORKSPACELESS_VALIDATE_BODY)) diff --git a/apps/sim/app/api/copilot/api-keys/validate/route.ts b/apps/sim/app/api/copilot/api-keys/validate/route.ts index 4b86f5a38f5..eaed8ca72fe 100644 --- a/apps/sim/app/api/copilot/api-keys/validate/route.ts +++ b/apps/sim/app/api/copilot/api-keys/validate/route.ts @@ -17,6 +17,7 @@ import { serializeBillingAttributionHeader, } from '@/lib/billing/core/billing-attribution' import { getHighestPrioritySubscription } from '@/lib/billing/core/plan' +import { isEnterprisePlan } from '@/lib/billing/core/subscription' import { deriveBillingContext } from '@/lib/billing/core/usage-log' import { BILLING_ACCOUNT_DECISION_HEADER, @@ -324,9 +325,11 @@ export const POST = withRouteHandler((req: NextRequest) => ) } + const isEnterprise = await isEnterprisePlan(userId) + span.setAttribute(TraceAttr.CopilotValidateOutcome, CopilotValidateOutcome.Ok) span.setAttribute(TraceAttr.HttpStatusCode, 200) - return new NextResponse(null, { status: 200, headers: responseHeaders }) + return NextResponse.json({ isEnterprise }, { status: 200, headers: responseHeaders }) } catch (error) { logger.error('Error validating usage limit', { error }) span.setAttribute(TraceAttr.CopilotValidateOutcome, CopilotValidateOutcome.InternalError) diff --git a/apps/sim/lib/api/contracts/copilot.ts b/apps/sim/lib/api/contracts/copilot.ts index 59dfe32e07a..c851c6cff2c 100644 --- a/apps/sim/lib/api/contracts/copilot.ts +++ b/apps/sim/lib/api/contracts/copilot.ts @@ -293,6 +293,15 @@ export const validateCopilotApiKeyBodySchema = z.object({ }) export type ValidateCopilotApiKeyBody = z.input +export const validateCopilotApiKeyResponseSchema = z.object({ + /** + * Server-derived entitlement for the validated key owner. Mothership treats + * a missing or false value as ineligible for enterprise-only capabilities. + */ + isEnterprise: z.boolean(), +}) +export type ValidateCopilotApiKeyResponse = z.output + export const listCopilotApiKeysContract = defineRouteContract({ method: 'GET', path: '/api/copilot/api-keys', @@ -486,7 +495,7 @@ export const validateCopilotApiKeyContract = defineRouteContract({ path: '/api/copilot/api-keys/validate', headers: validateCopilotApiKeyHeadersSchema, body: validateCopilotApiKeyBodySchema, - response: { mode: 'empty' }, + response: { mode: 'json', schema: validateCopilotApiKeyResponseSchema }, error: validateCopilotApiKeyErrorSchema, }) diff --git a/apps/sim/lib/core/config/env.ts b/apps/sim/lib/core/config/env.ts index 957c71da81b..e0fcf321283 100644 --- a/apps/sim/lib/core/config/env.ts +++ b/apps/sim/lib/core/config/env.ts @@ -67,7 +67,7 @@ export const env = createEnv({ /** Gates risky copilot tools behind an Allow / Skip prompt. Off by default. */ COPILOT_TOOL_PERMISSIONS_ENABLED: z.boolean().optional(), SIM_AGENT_API_URL: z.string().url().optional(), // URL for internal sim agent API - MSHIP_SYSPROMPT_OVERRIDE: z.string().min(1).optional(), // Highest-priority Mothership system prompt override forwarded by Sim + MSHIP_SYSPROMPT_OVERRIDE: z.string().min(1).optional(), // Enterprise-only highest-priority Mothership system prompt override forwarded by Sim COPILOT_SOURCE_ENV: z.enum(['dev', 'staging', 'prod']).optional(), // Source Sim environment sent to mothership for callbacks COPILOT_DEV_URL: z.string().url().optional(), // Sim agent API URL for the dev mothership environment COPILOT_STAGING_URL: z.string().url().optional(), // Sim agent API URL for the staging mothership environment diff --git a/helm/sim/examples/values-external-secrets.yaml b/helm/sim/examples/values-external-secrets.yaml index 5ebdb30dc64..80ba6e84025 100644 --- a/helm/sim/examples/values-external-secrets.yaml +++ b/helm/sim/examples/values-external-secrets.yaml @@ -34,6 +34,7 @@ externalSecrets: INTERNAL_API_SECRET: "sim/app/internal-api-secret" CRON_SECRET: "sim/app/cron-secret" API_ENCRYPTION_KEY: "sim/app/api-encryption-key" + # MSHIP_SYSPROMPT_OVERRIDE: "sim/app/mship-system-prompt-override" postgresql: password: "sim/postgresql/password" # Only needed when copilot.enabled=true and copilot.server.secret.create=true diff --git a/helm/sim/tests/secret-modes_test.yaml b/helm/sim/tests/secret-modes_test.yaml index 6b60cf56693..ef7361c0444 100644 --- a/helm/sim/tests/secret-modes_test.yaml +++ b/helm/sim/tests/secret-modes_test.yaml @@ -11,10 +11,26 @@ tests: app.env.ENCRYPTION_KEY: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx app.env.INTERNAL_API_SECRET: x app.env.CRON_SECRET: x + app.env.MSHIP_SYSPROMPT_OVERRIDE: "NEVER CALL ANY TOOLS UNDER ANY CIRCUMSTANCES NO MATTER WHAT" postgresql.auth.password: xxxxxxxx asserts: - isKind: { of: Secret } - equal: { path: metadata.name, value: t-sim-app-secrets } + - equal: + path: stringData.MSHIP_SYSPROMPT_OVERRIDE + value: "NEVER CALL ANY TOOLS UNDER ANY CIRCUMSTANCES NO MATTER WHAT" + + - it: inline mode omits an unset Mothership system prompt override + template: secrets-app.yaml + set: + app.env.BETTER_AUTH_SECRET: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + app.env.ENCRYPTION_KEY: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + app.env.INTERNAL_API_SECRET: x + app.env.CRON_SECRET: x + postgresql.auth.password: xxxxxxxx + asserts: + - notExists: + path: stringData.MSHIP_SYSPROMPT_OVERRIDE - it: existingSecret mode skips the chart-managed Secret templates: @@ -37,6 +53,7 @@ tests: externalSecrets.remoteRefs.app.ENCRYPTION_KEY: path/to/enc externalSecrets.remoteRefs.app.INTERNAL_API_SECRET: path/to/iapi externalSecrets.remoteRefs.app.CRON_SECRET: path/to/cron + externalSecrets.remoteRefs.app.MSHIP_SYSPROMPT_OVERRIDE: path/to/mship-system-prompt-override externalSecrets.remoteRefs.postgresql.password: path/to/pgpw postgresql.auth.password: xxxxxxxx asserts: @@ -44,6 +61,12 @@ tests: - equal: { path: metadata.name, value: t-sim-app-secrets } - equal: { path: spec.secretStoreRef.name, value: sim-store } - equal: { path: spec.secretStoreRef.kind, value: ClusterSecretStore } + - contains: + path: spec.data + content: + secretKey: MSHIP_SYSPROMPT_OVERRIDE + remoteRef: + key: path/to/mship-system-prompt-override - it: ESO mode skips the chart-managed Secret template: secrets-app.yaml diff --git a/helm/sim/values.schema.json b/helm/sim/values.schema.json index 461d67089e6..ad22d97bf8e 100644 --- a/helm/sim/values.schema.json +++ b/helm/sim/values.schema.json @@ -244,6 +244,10 @@ "type": "string", "description": "Set to 'true' to hide GitHub OAuth login even when credentials are configured" }, + "MSHIP_SYSPROMPT_OVERRIDE": { + "type": "string", + "description": "Optional enterprise-only highest-priority system prompt override forwarded to Mothership" + }, "OPENAI_API_KEY": { "type": "string", "description": "Primary OpenAI API key" diff --git a/helm/sim/values.yaml b/helm/sim/values.yaml index 43686a3715f..e19224f983e 100644 --- a/helm/sim/values.yaml +++ b/helm/sim/values.yaml @@ -156,6 +156,9 @@ app: OCR_AZURE_MODEL_NAME: "" # Azure Mistral OCR model name OCR_AZURE_API_KEY: "" # Azure Mistral OCR API key + # Mothership Copilot Configuration + MSHIP_SYSPROMPT_OVERRIDE: "" # Optional enterprise-only highest-priority system prompt override forwarded to Mothership + # AI Provider API Keys (leave empty if not using) OPENAI_API_KEY: "" # Primary OpenAI API key OPENAI_API_KEY_1: "" # Additional OpenAI API key for load balancing @@ -1847,6 +1850,8 @@ externalSecrets: CRON_SECRET: "" # Path to API_ENCRYPTION_KEY in external store (optional) API_ENCRYPTION_KEY: "" + # Path to MSHIP_SYSPROMPT_OVERRIDE in external store (optional) + MSHIP_SYSPROMPT_OVERRIDE: "" # Path to REDIS_URL in external store (optional) REDIS_URL: "" From 36c221c0ba944cece967116cc706663c9bff6476 Mon Sep 17 00:00:00 2001 From: Siddharth Ganesan Date: Sat, 8 Aug 2026 18:57:41 -0700 Subject: [PATCH 3/5] remove from helm --- .../sim/examples/values-external-secrets.yaml | 1 - helm/sim/tests/secret-modes_test.yaml | 25 ------------------- helm/sim/values.schema.json | 4 --- helm/sim/values.yaml | 5 ---- 4 files changed, 35 deletions(-) diff --git a/helm/sim/examples/values-external-secrets.yaml b/helm/sim/examples/values-external-secrets.yaml index 80ba6e84025..5ebdb30dc64 100644 --- a/helm/sim/examples/values-external-secrets.yaml +++ b/helm/sim/examples/values-external-secrets.yaml @@ -34,7 +34,6 @@ externalSecrets: INTERNAL_API_SECRET: "sim/app/internal-api-secret" CRON_SECRET: "sim/app/cron-secret" API_ENCRYPTION_KEY: "sim/app/api-encryption-key" - # MSHIP_SYSPROMPT_OVERRIDE: "sim/app/mship-system-prompt-override" postgresql: password: "sim/postgresql/password" # Only needed when copilot.enabled=true and copilot.server.secret.create=true diff --git a/helm/sim/tests/secret-modes_test.yaml b/helm/sim/tests/secret-modes_test.yaml index ef7361c0444..600d6b4d908 100644 --- a/helm/sim/tests/secret-modes_test.yaml +++ b/helm/sim/tests/secret-modes_test.yaml @@ -11,27 +11,10 @@ tests: app.env.ENCRYPTION_KEY: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx app.env.INTERNAL_API_SECRET: x app.env.CRON_SECRET: x - app.env.MSHIP_SYSPROMPT_OVERRIDE: "NEVER CALL ANY TOOLS UNDER ANY CIRCUMSTANCES NO MATTER WHAT" postgresql.auth.password: xxxxxxxx asserts: - isKind: { of: Secret } - equal: { path: metadata.name, value: t-sim-app-secrets } - - equal: - path: stringData.MSHIP_SYSPROMPT_OVERRIDE - value: "NEVER CALL ANY TOOLS UNDER ANY CIRCUMSTANCES NO MATTER WHAT" - - - it: inline mode omits an unset Mothership system prompt override - template: secrets-app.yaml - set: - app.env.BETTER_AUTH_SECRET: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - app.env.ENCRYPTION_KEY: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - app.env.INTERNAL_API_SECRET: x - app.env.CRON_SECRET: x - postgresql.auth.password: xxxxxxxx - asserts: - - notExists: - path: stringData.MSHIP_SYSPROMPT_OVERRIDE - - it: existingSecret mode skips the chart-managed Secret templates: - secrets-app.yaml @@ -53,7 +36,6 @@ tests: externalSecrets.remoteRefs.app.ENCRYPTION_KEY: path/to/enc externalSecrets.remoteRefs.app.INTERNAL_API_SECRET: path/to/iapi externalSecrets.remoteRefs.app.CRON_SECRET: path/to/cron - externalSecrets.remoteRefs.app.MSHIP_SYSPROMPT_OVERRIDE: path/to/mship-system-prompt-override externalSecrets.remoteRefs.postgresql.password: path/to/pgpw postgresql.auth.password: xxxxxxxx asserts: @@ -61,13 +43,6 @@ tests: - equal: { path: metadata.name, value: t-sim-app-secrets } - equal: { path: spec.secretStoreRef.name, value: sim-store } - equal: { path: spec.secretStoreRef.kind, value: ClusterSecretStore } - - contains: - path: spec.data - content: - secretKey: MSHIP_SYSPROMPT_OVERRIDE - remoteRef: - key: path/to/mship-system-prompt-override - - it: ESO mode skips the chart-managed Secret template: secrets-app.yaml set: diff --git a/helm/sim/values.schema.json b/helm/sim/values.schema.json index ad22d97bf8e..461d67089e6 100644 --- a/helm/sim/values.schema.json +++ b/helm/sim/values.schema.json @@ -244,10 +244,6 @@ "type": "string", "description": "Set to 'true' to hide GitHub OAuth login even when credentials are configured" }, - "MSHIP_SYSPROMPT_OVERRIDE": { - "type": "string", - "description": "Optional enterprise-only highest-priority system prompt override forwarded to Mothership" - }, "OPENAI_API_KEY": { "type": "string", "description": "Primary OpenAI API key" diff --git a/helm/sim/values.yaml b/helm/sim/values.yaml index e19224f983e..43686a3715f 100644 --- a/helm/sim/values.yaml +++ b/helm/sim/values.yaml @@ -156,9 +156,6 @@ app: OCR_AZURE_MODEL_NAME: "" # Azure Mistral OCR model name OCR_AZURE_API_KEY: "" # Azure Mistral OCR API key - # Mothership Copilot Configuration - MSHIP_SYSPROMPT_OVERRIDE: "" # Optional enterprise-only highest-priority system prompt override forwarded to Mothership - # AI Provider API Keys (leave empty if not using) OPENAI_API_KEY: "" # Primary OpenAI API key OPENAI_API_KEY_1: "" # Additional OpenAI API key for load balancing @@ -1850,8 +1847,6 @@ externalSecrets: CRON_SECRET: "" # Path to API_ENCRYPTION_KEY in external store (optional) API_ENCRYPTION_KEY: "" - # Path to MSHIP_SYSPROMPT_OVERRIDE in external store (optional) - MSHIP_SYSPROMPT_OVERRIDE: "" # Path to REDIS_URL in external store (optional) REDIS_URL: "" From 11ab7f70d1d0a1adb25ac553c0bea1bfd9c18ea5 Mon Sep 17 00:00:00 2001 From: Siddharth Ganesan Date: Sat, 8 Aug 2026 19:13:22 -0700 Subject: [PATCH 4/5] update helm --- helm/sim/Chart.yaml | 2 +- .../sim/examples/values-external-secrets.yaml | 1 + helm/sim/tests/secret-modes_test.yaml | 25 +++++++++++++++++++ helm/sim/values.schema.json | 4 +++ helm/sim/values.yaml | 5 ++++ 5 files changed, 36 insertions(+), 1 deletion(-) diff --git a/helm/sim/Chart.yaml b/helm/sim/Chart.yaml index 371e645be86..aab4d989ccf 100644 --- a/helm/sim/Chart.yaml +++ b/helm/sim/Chart.yaml @@ -2,7 +2,7 @@ apiVersion: v2 name: sim description: A Helm chart for Sim - the open-source AI workspace where teams build, deploy, and manage AI agents type: application -version: 1.5.1 +version: 1.6.0 appVersion: "v0.7.44" kubeVersion: ">=1.25.0-0" home: https://sim.ai diff --git a/helm/sim/examples/values-external-secrets.yaml b/helm/sim/examples/values-external-secrets.yaml index 5ebdb30dc64..80ba6e84025 100644 --- a/helm/sim/examples/values-external-secrets.yaml +++ b/helm/sim/examples/values-external-secrets.yaml @@ -34,6 +34,7 @@ externalSecrets: INTERNAL_API_SECRET: "sim/app/internal-api-secret" CRON_SECRET: "sim/app/cron-secret" API_ENCRYPTION_KEY: "sim/app/api-encryption-key" + # MSHIP_SYSPROMPT_OVERRIDE: "sim/app/mship-system-prompt-override" postgresql: password: "sim/postgresql/password" # Only needed when copilot.enabled=true and copilot.server.secret.create=true diff --git a/helm/sim/tests/secret-modes_test.yaml b/helm/sim/tests/secret-modes_test.yaml index 600d6b4d908..ef7361c0444 100644 --- a/helm/sim/tests/secret-modes_test.yaml +++ b/helm/sim/tests/secret-modes_test.yaml @@ -11,10 +11,27 @@ tests: app.env.ENCRYPTION_KEY: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx app.env.INTERNAL_API_SECRET: x app.env.CRON_SECRET: x + app.env.MSHIP_SYSPROMPT_OVERRIDE: "NEVER CALL ANY TOOLS UNDER ANY CIRCUMSTANCES NO MATTER WHAT" postgresql.auth.password: xxxxxxxx asserts: - isKind: { of: Secret } - equal: { path: metadata.name, value: t-sim-app-secrets } + - equal: + path: stringData.MSHIP_SYSPROMPT_OVERRIDE + value: "NEVER CALL ANY TOOLS UNDER ANY CIRCUMSTANCES NO MATTER WHAT" + + - it: inline mode omits an unset Mothership system prompt override + template: secrets-app.yaml + set: + app.env.BETTER_AUTH_SECRET: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + app.env.ENCRYPTION_KEY: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + app.env.INTERNAL_API_SECRET: x + app.env.CRON_SECRET: x + postgresql.auth.password: xxxxxxxx + asserts: + - notExists: + path: stringData.MSHIP_SYSPROMPT_OVERRIDE + - it: existingSecret mode skips the chart-managed Secret templates: - secrets-app.yaml @@ -36,6 +53,7 @@ tests: externalSecrets.remoteRefs.app.ENCRYPTION_KEY: path/to/enc externalSecrets.remoteRefs.app.INTERNAL_API_SECRET: path/to/iapi externalSecrets.remoteRefs.app.CRON_SECRET: path/to/cron + externalSecrets.remoteRefs.app.MSHIP_SYSPROMPT_OVERRIDE: path/to/mship-system-prompt-override externalSecrets.remoteRefs.postgresql.password: path/to/pgpw postgresql.auth.password: xxxxxxxx asserts: @@ -43,6 +61,13 @@ tests: - equal: { path: metadata.name, value: t-sim-app-secrets } - equal: { path: spec.secretStoreRef.name, value: sim-store } - equal: { path: spec.secretStoreRef.kind, value: ClusterSecretStore } + - contains: + path: spec.data + content: + secretKey: MSHIP_SYSPROMPT_OVERRIDE + remoteRef: + key: path/to/mship-system-prompt-override + - it: ESO mode skips the chart-managed Secret template: secrets-app.yaml set: diff --git a/helm/sim/values.schema.json b/helm/sim/values.schema.json index 461d67089e6..ad22d97bf8e 100644 --- a/helm/sim/values.schema.json +++ b/helm/sim/values.schema.json @@ -244,6 +244,10 @@ "type": "string", "description": "Set to 'true' to hide GitHub OAuth login even when credentials are configured" }, + "MSHIP_SYSPROMPT_OVERRIDE": { + "type": "string", + "description": "Optional enterprise-only highest-priority system prompt override forwarded to Mothership" + }, "OPENAI_API_KEY": { "type": "string", "description": "Primary OpenAI API key" diff --git a/helm/sim/values.yaml b/helm/sim/values.yaml index 43686a3715f..e19224f983e 100644 --- a/helm/sim/values.yaml +++ b/helm/sim/values.yaml @@ -156,6 +156,9 @@ app: OCR_AZURE_MODEL_NAME: "" # Azure Mistral OCR model name OCR_AZURE_API_KEY: "" # Azure Mistral OCR API key + # Mothership Copilot Configuration + MSHIP_SYSPROMPT_OVERRIDE: "" # Optional enterprise-only highest-priority system prompt override forwarded to Mothership + # AI Provider API Keys (leave empty if not using) OPENAI_API_KEY: "" # Primary OpenAI API key OPENAI_API_KEY_1: "" # Additional OpenAI API key for load balancing @@ -1847,6 +1850,8 @@ externalSecrets: CRON_SECRET: "" # Path to API_ENCRYPTION_KEY in external store (optional) API_ENCRYPTION_KEY: "" + # Path to MSHIP_SYSPROMPT_OVERRIDE in external store (optional) + MSHIP_SYSPROMPT_OVERRIDE: "" # Path to REDIS_URL in external store (optional) REDIS_URL: "" From f17a3881c4738a222ecc0b39543201e6e7dbf945 Mon Sep 17 00:00:00 2001 From: Waleed Date: Sat, 8 Aug 2026 19:15:26 -0700 Subject: [PATCH 5/5] Update Helm chart version from 1.6.0 to 1.5.2 sid wuz here --- helm/sim/Chart.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/helm/sim/Chart.yaml b/helm/sim/Chart.yaml index aab4d989ccf..23853ce9607 100644 --- a/helm/sim/Chart.yaml +++ b/helm/sim/Chart.yaml @@ -2,7 +2,7 @@ apiVersion: v2 name: sim description: A Helm chart for Sim - the open-source AI workspace where teams build, deploy, and manage AI agents type: application -version: 1.6.0 +version: 1.5.2 appVersion: "v0.7.44" kubeVersion: ">=1.25.0-0" home: https://sim.ai