@ai-ecoverse/slicc-agent 3.52.1 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. package/README.md +17 -13
  2. package/dist/client.js +1 -1
  3. package/dist/client.js.map +1 -1
  4. package/dist/host.js.map +1 -1
  5. package/dist/index.js +0 -3
  6. package/dist/index.js.map +2 -2
  7. package/dist/main.js +95 -22
  8. package/dist/main.js.map +2 -2
  9. package/dist/mcp/accounts.js +18 -14
  10. package/dist/mcp/accounts.js.map +2 -2
  11. package/dist/mcp/connection.js +0 -2
  12. package/dist/mcp/connection.js.map +2 -2
  13. package/dist/mcp/credentials.js +6 -15
  14. package/dist/mcp/credentials.js.map +2 -2
  15. package/dist/mcp/index.js +0 -1
  16. package/dist/mcp/index.js.map +2 -2
  17. package/dist/mcp/oauth.js +15 -20
  18. package/dist/mcp/oauth.js.map +2 -2
  19. package/dist/mcp/runtime.js +36 -14
  20. package/dist/mcp/runtime.js.map +2 -2
  21. package/dist/mcp/tools.js +4 -6
  22. package/dist/mcp/tools.js.map +2 -2
  23. package/dist/models/index.js +7 -4
  24. package/dist/models/index.js.map +2 -2
  25. package/dist/monitor/index.js +5 -10
  26. package/dist/monitor/index.js.map +2 -2
  27. package/dist/monitor/redact.js +4 -5
  28. package/dist/monitor/redact.js.map +2 -2
  29. package/dist/secrets/credentials.js +32 -0
  30. package/dist/secrets/credentials.js.map +7 -0
  31. package/dist/secrets/endpoints.js +111 -0
  32. package/dist/secrets/endpoints.js.map +7 -0
  33. package/dist/secrets/fetch.js +160 -0
  34. package/dist/secrets/fetch.js.map +7 -0
  35. package/dist/secrets/records.js +35 -0
  36. package/dist/secrets/records.js.map +7 -0
  37. package/dist/secrets/store.js +50 -0
  38. package/dist/secrets/store.js.map +7 -0
  39. package/dist/secrets/vault.js +58 -13
  40. package/dist/secrets/vault.js.map +2 -2
  41. package/dist/services.js.map +2 -2
  42. package/dist/settings.js +85 -23
  43. package/dist/settings.js.map +2 -2
  44. package/dist/spectrum/settings-port.js +24 -6
  45. package/dist/spectrum/settings-port.js.map +2 -2
  46. package/dist/types/host.d.ts +1 -1
  47. package/dist/types/index.d.ts +0 -1
  48. package/dist/types/main.d.ts +7 -2
  49. package/dist/types/mcp/accounts.d.ts +10 -4
  50. package/dist/types/mcp/connection.d.ts +0 -2
  51. package/dist/types/mcp/credentials.d.ts +6 -4
  52. package/dist/types/mcp/oauth.d.ts +3 -2
  53. package/dist/types/mcp/runtime.d.ts +18 -4
  54. package/dist/types/models/index.d.ts +2 -0
  55. package/dist/types/monitor/index.d.ts +0 -1
  56. package/dist/types/monitor/redact.d.ts +2 -2
  57. package/dist/types/secrets/credentials.d.ts +5 -0
  58. package/dist/types/secrets/endpoints.d.ts +27 -0
  59. package/dist/types/secrets/fetch.d.ts +13 -0
  60. package/dist/types/secrets/records.d.ts +13 -0
  61. package/dist/types/secrets/store.d.ts +7 -0
  62. package/dist/types/secrets/vault.d.ts +31 -1
  63. package/dist/types/services.d.ts +8 -1
  64. package/dist/types/settings.d.ts +17 -2
  65. package/dist/types/spectrum/settings-port.d.ts +6 -4
  66. package/package.json +5 -3
  67. package/dist/credentials.js +0 -100
  68. package/dist/credentials.js.map +0 -7
  69. package/dist/types/credentials.d.ts +0 -12
package/dist/settings.js CHANGED
@@ -14,6 +14,12 @@ import { MCP_ACCOUNT } from "./mcp/label.js";
14
14
  const BEDROCK = "amazon-bedrock";
15
15
  const DEFAULT_MODEL = { provider: BEDROCK, modelId: "us.anthropic.claude-sonnet-5-5" };
16
16
  const DEFAULT_REGIONS = { [BEDROCK]: "us-west-2" };
17
+ const ACCOUNT_FIELDS = {
18
+ [BEDROCK]: [{ name: "region", label: "Region" }]
19
+ };
20
+ const FIELD_ENV = { region: "AWS_REGION" };
21
+ const SIGN_IN_NEEDS_VAULT = "Adobe sign-in needs seven's vault: update seven";
22
+ const KEY_NEEDS_VAULT = "API keys are kept in seven's vault: update seven";
17
23
  const corsFree = /* @__PURE__ */ new Set([BEDROCK, ADOBE]);
18
24
  const signIn = /* @__PURE__ */ new Set([ADOBE]);
19
25
  const BUDGET_EVERY = 5 * 60 * 1e3;
@@ -53,15 +59,52 @@ function choices(models, providers, stored) {
53
59
  }))
54
60
  );
55
61
  }
56
- function accounts(stored, providers) {
57
- return providers.map((provider) => ({
58
- id: provider.id,
59
- provider: provider.name ?? provider.id,
60
- identity: stored.has(provider.id) ? signIn.has(provider.id) ? "Adobe ID" : "API key" : "",
61
- status: stored.has(provider.id) ? "connected" : "disconnected",
62
- auth: signIn.has(provider.id) ? "oauth" : "api-key",
63
- needs: corsFree.has(provider.id) ? "cors-free-transport" : null
64
- }));
62
+ function accounts(records, providers) {
63
+ return providers.map((provider) => {
64
+ const record = records.model(provider.id);
65
+ const fields = ACCOUNT_FIELDS[provider.id];
66
+ return {
67
+ id: provider.id,
68
+ provider: provider.name ?? provider.id,
69
+ identity: record ? signIn.has(provider.id) ? "Adobe ID" : "API key" : "",
70
+ status: !record ? "disconnected" : record.state === "expired" ? "expired" : "connected",
71
+ auth: signIn.has(provider.id) ? "oauth" : "api-key",
72
+ needs: corsFree.has(provider.id) ? "cors-free-transport" : null,
73
+ store: "vault",
74
+ ...fields ? { fields: fields.map((field) => ({ ...field })) } : {}
75
+ };
76
+ });
77
+ }
78
+ async function providerFields(store, providers) {
79
+ const known = /* @__PURE__ */ new Map();
80
+ for (const provider of providers) {
81
+ const saved = await store.get(`model:${provider.id}`);
82
+ if (saved && typeof saved === "object") known.set(provider.id, saved);
83
+ }
84
+ return {
85
+ get: (providerId) => known.get(providerId),
86
+ env(providerId) {
87
+ const fields = known.get(providerId);
88
+ if (!fields) return void 0;
89
+ return Object.fromEntries(
90
+ Object.entries(fields).flatMap(
91
+ ([name, value]) => FIELD_ENV[name] ? [[FIELD_ENV[name], value]] : []
92
+ )
93
+ );
94
+ },
95
+ async set(providerId, fields) {
96
+ const allowed = new Set((ACCOUNT_FIELDS[providerId] ?? []).map((field) => field.name));
97
+ const kept = Object.fromEntries(
98
+ Object.entries(fields ?? {}).filter(
99
+ ([name, value]) => allowed.has(name) && typeof value === "string" && value.trim() !== ""
100
+ )
101
+ );
102
+ const next = Object.keys(kept).length ? kept : void 0;
103
+ if (next) known.set(providerId, next);
104
+ else known.delete(providerId);
105
+ await store.set(`model:${providerId}`, next);
106
+ }
107
+ };
65
108
  }
66
109
  async function shown(run) {
67
110
  try {
@@ -73,25 +116,27 @@ async function shown(run) {
73
116
  );
74
117
  }
75
118
  }
76
- async function budget(credentials, usage) {
77
- const credential = await credentials.read(ADOBE);
78
- const key = credential?.type === "api_key" ? credential.key : void 0;
119
+ async function budget(records, usage) {
120
+ const key = records.model(ADOBE)?.placeholder;
79
121
  const found = key ? await usage(key).catch(() => null) : null;
80
122
  return found ? { provider: ADOBE, ...found } : null;
81
123
  }
82
- async function createAgentSettings(models, credentials, providers = sliccProviders(), options = {}) {
124
+ async function createAgentSettings(models, sources, providers = sliccProviders(), options = {}) {
83
125
  const { mcp } = options;
126
+ const { records, fields } = sources;
84
127
  const routed = (providerId) => providerId.startsWith(MCP_ACCOUNT) ? mcp : void 0;
85
128
  const adobe = providers.find((provider) => provider.id === ADOBE);
86
129
  const endpoint = adobe?.baseUrl ?? ADOBE_PROXY;
87
130
  const identity = adobe?.headers ?? adobeIdentity();
88
131
  const usage = options.usage ?? ((token) => adobeUsage(token, { endpoint, identity }));
89
132
  const snapshot = async () => {
90
- const stored = new Set((await credentials.list()).map((info) => info.providerId));
133
+ const stored = new Set(
134
+ providers.filter((provider) => records.model(provider.id)).map((provider) => provider.id)
135
+ );
91
136
  return {
92
137
  models: choices(models, providers, stored),
93
- accounts: [...accounts(stored, providers), ...await mcp?.accounts() ?? []],
94
- budget: await budget(credentials, usage)
138
+ accounts: [...accounts(records, providers), ...await mcp?.accounts() ?? []],
139
+ budget: await budget(records, usage)
95
140
  };
96
141
  };
97
142
  const state = replicatedState(await snapshot());
@@ -113,20 +158,32 @@ async function createAgentSettings(models, credentials, providers = sliccProvide
113
158
  timer.unref?.();
114
159
  }
115
160
  mcp?.onChange(() => void refresh(BACKGROUND_CONTEXT).catch(() => void 0));
161
+ const held = () => signedIn.filter((id) => records.model(id)).join(" ");
162
+ let seen = held();
163
+ records.state.subscribe(() => {
164
+ const now = held();
165
+ const added = now !== seen;
166
+ seen = now;
167
+ const discovered = added ? discover(signedIn) : Promise.resolve();
168
+ void discovered.then(() => refresh(BACKGROUND_CONTEXT)).catch(() => void 0);
169
+ });
170
+ const reread = (context) => records.refresh(context).catch(() => void 0);
116
171
  return {
117
172
  state,
118
- async connect(providerId, secret, region, context) {
173
+ async connect(providerId, secret, given, context) {
119
174
  const server = routed(providerId);
120
175
  if (server) {
121
176
  await shown(() => server.connect(providerId, secret));
122
177
  await refresh(context);
123
178
  return;
124
179
  }
125
- await credentials.modify(providerId, async () => ({
126
- type: "api_key",
127
- key: secret,
128
- ...region ? { env: { AWS_REGION: region } } : {}
129
- }));
180
+ if (secret !== null)
181
+ throw new RemoteServiceError(
182
+ "service_invalid_value",
183
+ signIn.has(providerId) ? SIGN_IN_NEEDS_VAULT : KEY_NEEDS_VAULT
184
+ );
185
+ if (given !== null) await fields.set(providerId, given);
186
+ await reread(context);
130
187
  if (signIn.has(providerId)) await discover([providerId]);
131
188
  await refresh(context);
132
189
  },
@@ -144,17 +201,22 @@ async function createAgentSettings(models, credentials, providers = sliccProvide
144
201
  async disconnect(providerId, context) {
145
202
  const server = routed(providerId);
146
203
  if (server) await server.disconnect(providerId);
147
- else await credentials.delete(providerId);
204
+ else await fields.set(providerId, void 0);
205
+ await reread(context);
148
206
  await refresh(context);
149
207
  }
150
208
  };
151
209
  }
152
210
  export {
211
+ ACCOUNT_FIELDS,
153
212
  BEDROCK,
154
213
  DEFAULT_MODEL,
155
214
  DEFAULT_REGIONS,
215
+ KEY_NEEDS_VAULT,
216
+ SIGN_IN_NEEDS_VAULT,
156
217
  createAgentSettings,
157
218
  createSliccModels,
219
+ providerFields,
158
220
  shown,
159
221
  sliccProviders,
160
222
  withDefaultRegions
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/settings.ts"],
4
- "sourcesContent": ["import { type Context, RemoteServiceError, replicatedState } from '@earendil-works/chord';\nimport { BACKGROUND_CONTEXT } from '@earendil-works/chord/context';\nimport type { CredentialStore, Provider } from '@earendil-works/pi-ai';\nimport { createModels, type MutableModels } from '@earendil-works/pi-ai/models';\nimport { amazonBedrockProvider } from '@earendil-works/pi-ai/providers/amazon-bedrock';\nimport {\n ADOBE,\n ADOBE_PROXY,\n adobeConfig,\n adobeIdentity,\n adobeProvider,\n adobeUsage,\n type Budget,\n} from './adobe.ts';\nimport type { McpAccounts } from './mcp/index.ts';\nimport { MCP_ACCOUNT } from './mcp/label.ts';\nimport type { AccountState, AgentSettings, ModelChoice, SettingsState } from './services.ts';\n\nexport const BEDROCK = 'amazon-bedrock';\nexport const DEFAULT_MODEL = { provider: BEDROCK, modelId: 'us.anthropic.claude-sonnet-5-5' };\nexport const DEFAULT_REGIONS: Readonly<Record<string, string>> = { [BEDROCK]: 'us-west-2' };\n\nconst corsFree = new Set([BEDROCK, ADOBE]);\nconst signIn = new Set([ADOBE]);\nconst BUDGET_EVERY = 5 * 60 * 1000;\n\nexport function sliccProviders(version?: string): Provider[] {\n return [amazonBedrockProvider() as Provider, adobeProvider({ version })];\n}\n\nexport function withDefaultRegions(credentials: CredentialStore): CredentialStore {\n return {\n async read(providerId, options) {\n const credential = await credentials.read(providerId, options);\n const region = DEFAULT_REGIONS[providerId];\n if (credential?.type !== 'api_key' || !region || credential.env?.AWS_REGION) {\n return credential;\n }\n return { ...credential, env: { ...credential.env, AWS_REGION: region } };\n },\n list: (options) => credentials.list(options),\n modify: (providerId, fn, options) => credentials.modify(providerId, fn, options),\n delete: (providerId, options) => credentials.delete(providerId, options),\n };\n}\n\nexport function createSliccModels(\n credentials: CredentialStore,\n providers = sliccProviders()\n): MutableModels {\n const models = createModels({ credentials: withDefaultRegions(credentials) });\n for (const provider of providers) models.setProvider(provider);\n return models;\n}\n\nfunction choices(\n models: MutableModels,\n providers: Provider[],\n stored: ReadonlySet<string>\n): ModelChoice[] {\n return providers\n .filter((provider) => stored.has(provider.id))\n .flatMap((provider) =>\n models.getModels(provider.id).map((model) => ({\n id: `${provider.id}/${model.id}`,\n label: model.name,\n provider: provider.name ?? provider.id,\n kind: 'chat' as const,\n reasoning: Boolean(model.reasoning),\n images: model.input.includes('image'),\n contextWindow: model.contextWindow,\n }))\n );\n}\n\nfunction accounts(stored: ReadonlySet<string>, providers: Provider[]): AccountState[] {\n return providers.map((provider) => ({\n id: provider.id,\n provider: provider.name ?? provider.id,\n identity: stored.has(provider.id) ? (signIn.has(provider.id) ? 'Adobe ID' : 'API key') : '',\n status: stored.has(provider.id) ? 'connected' : 'disconnected',\n auth: signIn.has(provider.id) ? 'oauth' : 'api-key',\n needs: corsFree.has(provider.id) ? 'cors-free-transport' : null,\n }));\n}\n\nexport async function shown<T>(run: () => Promise<T>): Promise<T> {\n try {\n return await run();\n } catch (error) {\n throw new RemoteServiceError(\n 'service_invalid_value',\n error instanceof Error ? error.message : String(error)\n );\n }\n}\n\nexport type UsageReader = (token: string) => Promise<Budget | null>;\n\nasync function budget(credentials: CredentialStore, usage: UsageReader) {\n const credential = await credentials.read(ADOBE);\n const key = credential?.type === 'api_key' ? credential.key : undefined;\n const found = key ? await usage(key).catch(() => null) : null;\n return found ? { provider: ADOBE, ...found } : null;\n}\n\nexport async function createAgentSettings(\n models: MutableModels,\n credentials: CredentialStore,\n providers = sliccProviders(),\n options: { usage?: UsageReader; every?: number; mcp?: McpAccounts } = {}\n): Promise<AgentSettings> {\n const { mcp } = options;\n const routed = (providerId: string) => (providerId.startsWith(MCP_ACCOUNT) ? mcp : undefined);\n const adobe = providers.find((provider) => provider.id === ADOBE);\n const endpoint = adobe?.baseUrl ?? ADOBE_PROXY;\n const identity = (adobe?.headers as Record<string, string> | undefined) ?? adobeIdentity();\n const usage = options.usage ?? ((token: string) => adobeUsage(token, { endpoint, identity }));\n const snapshot = async (): Promise<SettingsState> => {\n const stored = new Set((await credentials.list()).map((info) => info.providerId));\n return {\n models: choices(models, providers, stored),\n accounts: [...accounts(stored, providers), ...((await mcp?.accounts()) ?? [])],\n budget: await budget(credentials, usage),\n };\n };\n const state = replicatedState<SettingsState>(await snapshot());\n let latest = Promise.resolve();\n const refresh = (context: Context) => {\n const next = latest.then(async () => state.replace(context, await snapshot()));\n latest = next.catch(() => undefined);\n return next;\n };\n const signedIn = providers\n .filter((provider) => signIn.has(provider.id))\n .map((provider) => provider.id);\n const discover = (ids: string[]) =>\n models.refresh({ providers: ids }).then(\n () => undefined,\n () => undefined\n );\n if (signedIn.length) {\n const cycle = () =>\n void discover(signedIn)\n .then(() => refresh(BACKGROUND_CONTEXT))\n .catch(() => undefined);\n cycle();\n const timer: unknown = setInterval(cycle, options.every ?? BUDGET_EVERY);\n (timer as { unref?: () => void }).unref?.();\n }\n mcp?.onChange(() => void refresh(BACKGROUND_CONTEXT).catch(() => undefined));\n return {\n state,\n async connect(providerId, secret, region, context) {\n const server = routed(providerId);\n if (server) {\n await shown(() => server.connect(providerId, secret));\n await refresh(context);\n return;\n }\n await credentials.modify(providerId, async () => ({\n type: 'api_key',\n key: secret,\n ...(region ? { env: { AWS_REGION: region } } : {}),\n }));\n if (signIn.has(providerId)) await discover([providerId]);\n await refresh(context);\n },\n async signIn(providerId) {\n const server = routed(providerId);\n if (server) return shown(() => server.signIn(providerId));\n if (providerId !== ADOBE) return null;\n const { clientId, scopes, imsEnvironment } = await adobeConfig(\n endpoint,\n (input, init) => globalThis.fetch(input, init),\n identity\n );\n return { clientId, scopes, imsEnvironment: imsEnvironment || 'prod' };\n },\n async disconnect(providerId, context) {\n const server = routed(providerId);\n if (server) await server.disconnect(providerId);\n else await credentials.delete(providerId);\n await refresh(context);\n },\n };\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { type Context, RemoteServiceError, replicatedState } from '@earendil-works/chord';\nimport { BACKGROUND_CONTEXT } from '@earendil-works/chord/context';\nimport type { CredentialStore, Provider } from '@earendil-works/pi-ai';\nimport { createModels, type MutableModels } from '@earendil-works/pi-ai/models';\nimport { amazonBedrockProvider } from '@earendil-works/pi-ai/providers/amazon-bedrock';\nimport {\n ADOBE,\n ADOBE_PROXY,\n adobeConfig,\n adobeIdentity,\n adobeProvider,\n adobeUsage,\n type Budget,\n} from './adobe.ts';\nimport type { McpAccounts } from './mcp/index.ts';\nimport { MCP_ACCOUNT } from './mcp/label.ts';\nimport type { VaultRecords } from './secrets/records.ts';\nimport type { PlainStore } from './secrets/store.ts';\nimport type {\n AccountField,\n AccountState,\n AgentSettings,\n ModelChoice,\n SettingsState,\n} from './services.ts';\n\nexport const BEDROCK = 'amazon-bedrock';\nexport const DEFAULT_MODEL = { provider: BEDROCK, modelId: 'us.anthropic.claude-sonnet-5-5' };\nexport const DEFAULT_REGIONS: Readonly<Record<string, string>> = { [BEDROCK]: 'us-west-2' };\n\nexport const ACCOUNT_FIELDS: Readonly<Record<string, readonly AccountField[]>> = {\n [BEDROCK]: [{ name: 'region', label: 'Region' }],\n};\nconst FIELD_ENV: Readonly<Record<string, string>> = { region: 'AWS_REGION' };\nexport const SIGN_IN_NEEDS_VAULT = \"Adobe sign-in needs seven's vault: update seven\";\nexport const KEY_NEEDS_VAULT = \"API keys are kept in seven's vault: update seven\";\n\nconst corsFree = new Set([BEDROCK, ADOBE]);\nconst signIn = new Set([ADOBE]);\nconst BUDGET_EVERY = 5 * 60 * 1000;\n\nexport function sliccProviders(version?: string): Provider[] {\n return [amazonBedrockProvider() as Provider, adobeProvider({ version })];\n}\n\nexport function withDefaultRegions(credentials: CredentialStore): CredentialStore {\n return {\n async read(providerId, options) {\n const credential = await credentials.read(providerId, options);\n const region = DEFAULT_REGIONS[providerId];\n if (credential?.type !== 'api_key' || !region || credential.env?.AWS_REGION) {\n return credential;\n }\n return { ...credential, env: { ...credential.env, AWS_REGION: region } };\n },\n list: (options) => credentials.list(options),\n modify: (providerId, fn, options) => credentials.modify(providerId, fn, options),\n delete: (providerId, options) => credentials.delete(providerId, options),\n };\n}\n\nexport function createSliccModels(\n credentials: CredentialStore,\n providers = sliccProviders()\n): MutableModels {\n const models = createModels({ credentials: withDefaultRegions(credentials) });\n for (const provider of providers) models.setProvider(provider);\n return models;\n}\n\nfunction choices(\n models: MutableModels,\n providers: Provider[],\n stored: ReadonlySet<string>\n): ModelChoice[] {\n return providers\n .filter((provider) => stored.has(provider.id))\n .flatMap((provider) =>\n models.getModels(provider.id).map((model) => ({\n id: `${provider.id}/${model.id}`,\n label: model.name,\n provider: provider.name ?? provider.id,\n kind: 'chat' as const,\n reasoning: Boolean(model.reasoning),\n images: model.input.includes('image'),\n contextWindow: model.contextWindow,\n }))\n );\n}\n\nfunction accounts(records: Pick<VaultRecords, 'model'>, providers: Provider[]): AccountState[] {\n return providers.map((provider) => {\n const record = records.model(provider.id);\n const fields = ACCOUNT_FIELDS[provider.id];\n return {\n id: provider.id,\n provider: provider.name ?? provider.id,\n identity: record ? (signIn.has(provider.id) ? 'Adobe ID' : 'API key') : '',\n status: !record ? 'disconnected' : record.state === 'expired' ? 'expired' : 'connected',\n auth: signIn.has(provider.id) ? 'oauth' : 'api-key',\n needs: corsFree.has(provider.id) ? 'cors-free-transport' : null,\n store: 'vault',\n ...(fields ? { fields: fields.map((field) => ({ ...field })) } : {}),\n };\n });\n}\n\nexport interface ProviderFields {\n get(providerId: string): Readonly<Record<string, string>> | undefined;\n env(providerId: string): Readonly<Record<string, string>> | undefined;\n set(providerId: string, fields: Record<string, string> | undefined): Promise<void>;\n}\n\nexport async function providerFields(\n store: PlainStore,\n providers: readonly Provider[]\n): Promise<ProviderFields> {\n const known = new Map<string, Record<string, string>>();\n for (const provider of providers) {\n const saved = (await store.get(`model:${provider.id}`)) as Record<string, string> | undefined;\n if (saved && typeof saved === 'object') known.set(provider.id, saved);\n }\n return {\n get: (providerId) => known.get(providerId),\n env(providerId) {\n const fields = known.get(providerId);\n if (!fields) return undefined;\n return Object.fromEntries(\n Object.entries(fields).flatMap(([name, value]) =>\n FIELD_ENV[name] ? [[FIELD_ENV[name], value]] : []\n )\n );\n },\n async set(providerId, fields) {\n const allowed = new Set((ACCOUNT_FIELDS[providerId] ?? []).map((field) => field.name));\n const kept = Object.fromEntries(\n Object.entries(fields ?? {}).filter(\n ([name, value]) => allowed.has(name) && typeof value === 'string' && value.trim() !== ''\n )\n );\n const next = Object.keys(kept).length ? kept : undefined;\n if (next) known.set(providerId, next);\n else known.delete(providerId);\n await store.set(`model:${providerId}`, next);\n },\n };\n}\n\nexport async function shown<T>(run: () => Promise<T>): Promise<T> {\n try {\n return await run();\n } catch (error) {\n throw new RemoteServiceError(\n 'service_invalid_value',\n error instanceof Error ? error.message : String(error)\n );\n }\n}\n\nexport type UsageReader = (token: string) => Promise<Budget | null>;\n\nasync function budget(records: Pick<VaultRecords, 'model'>, usage: UsageReader) {\n const key = records.model(ADOBE)?.placeholder;\n const found = key ? await usage(key).catch(() => null) : null;\n return found ? { provider: ADOBE, ...found } : null;\n}\n\nexport interface SettingsSources {\n records: VaultRecords;\n fields: ProviderFields;\n}\n\nexport async function createAgentSettings(\n models: MutableModels,\n sources: SettingsSources,\n providers = sliccProviders(),\n options: { usage?: UsageReader; every?: number; mcp?: McpAccounts } = {}\n): Promise<AgentSettings> {\n const { mcp } = options;\n const { records, fields } = sources;\n const routed = (providerId: string) => (providerId.startsWith(MCP_ACCOUNT) ? mcp : undefined);\n const adobe = providers.find((provider) => provider.id === ADOBE);\n const endpoint = adobe?.baseUrl ?? ADOBE_PROXY;\n const identity = (adobe?.headers as Record<string, string> | undefined) ?? adobeIdentity();\n const usage = options.usage ?? ((token: string) => adobeUsage(token, { endpoint, identity }));\n const snapshot = async (): Promise<SettingsState> => {\n const stored = new Set(\n providers.filter((provider) => records.model(provider.id)).map((provider) => provider.id)\n );\n return {\n models: choices(models, providers, stored),\n accounts: [...accounts(records, providers), ...((await mcp?.accounts()) ?? [])],\n budget: await budget(records, usage),\n };\n };\n const state = replicatedState<SettingsState>(await snapshot());\n let latest = Promise.resolve();\n const refresh = (context: Context) => {\n const next = latest.then(async () => state.replace(context, await snapshot()));\n latest = next.catch(() => undefined);\n return next;\n };\n const signedIn = providers\n .filter((provider) => signIn.has(provider.id))\n .map((provider) => provider.id);\n const discover = (ids: string[]) =>\n models.refresh({ providers: ids }).then(\n () => undefined,\n () => undefined\n );\n if (signedIn.length) {\n const cycle = () =>\n void discover(signedIn)\n .then(() => refresh(BACKGROUND_CONTEXT))\n .catch(() => undefined);\n cycle();\n const timer: unknown = setInterval(cycle, options.every ?? BUDGET_EVERY);\n (timer as { unref?: () => void }).unref?.();\n }\n mcp?.onChange(() => void refresh(BACKGROUND_CONTEXT).catch(() => undefined));\n const held = () => signedIn.filter((id) => records.model(id)).join(' ');\n let seen = held();\n records.state.subscribe(() => {\n const now = held();\n const added = now !== seen;\n seen = now;\n const discovered = added ? discover(signedIn) : Promise.resolve();\n void discovered.then(() => refresh(BACKGROUND_CONTEXT)).catch(() => undefined);\n });\n const reread = (context: Context) => records.refresh(context).catch(() => undefined);\n return {\n state,\n async connect(providerId, secret, given, context) {\n const server = routed(providerId);\n if (server) {\n await shown(() => server.connect(providerId, secret));\n await refresh(context);\n return;\n }\n if (secret !== null)\n throw new RemoteServiceError(\n 'service_invalid_value',\n signIn.has(providerId) ? SIGN_IN_NEEDS_VAULT : KEY_NEEDS_VAULT\n );\n if (given !== null) await fields.set(providerId, given);\n await reread(context);\n if (signIn.has(providerId)) await discover([providerId]);\n await refresh(context);\n },\n async signIn(providerId) {\n const server = routed(providerId);\n if (server) return shown(() => server.signIn(providerId));\n if (providerId !== ADOBE) return null;\n const { clientId, scopes, imsEnvironment } = await adobeConfig(\n endpoint,\n (input, init) => globalThis.fetch(input, init),\n identity\n );\n return { clientId, scopes, imsEnvironment: imsEnvironment || 'prod' };\n },\n async disconnect(providerId, context) {\n const server = routed(providerId);\n if (server) await server.disconnect(providerId);\n else await fields.set(providerId, undefined);\n await reread(context);\n await refresh(context);\n },\n };\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -11,6 +11,7 @@ const defaults = {
11
11
  showThinking: false,
12
12
  diffStyle: "unified"
13
13
  };
14
+ const SIGN_IN_NEEDS_VAULT = "Adobe sign-in needs seven's vault: update seven";
14
15
  class SettingsAdapter extends Emitter {
15
16
  #settings;
16
17
  #agent;
@@ -67,13 +68,29 @@ class SettingsAdapter extends Emitter {
67
68
  return needs ? { ...shown, needs } : shown;
68
69
  });
69
70
  }
70
- async connect(id, secret, options = {}) {
71
+ async connect(id, secret, fields) {
71
72
  const account = this.#state().accounts.find((candidate) => candidate.id === id);
72
- const login = account?.auth !== "oauth" ? null : account.group === "mcp" ? this.#mcpLogin : this.#login;
73
- const key = secret ?? (login ? await this.#signIn(id, login) : void 0);
74
- if (!key)
75
- throw new Error(`${id} needs ${account?.auth === "oauth" ? "a sign-in" : "an API key"}`);
76
- await this.#settings.connect(id, key, options.region ?? null, BACKGROUND_CONTEXT);
73
+ const mcp = account?.group === "mcp";
74
+ const login = account?.auth !== "oauth" ? null : mcp ? this.#mcpLogin : this.#login;
75
+ const given = fields ? { ...fields } : null;
76
+ if (secret !== void 0) {
77
+ await this.#settings.connect(id, secret, given, BACKGROUND_CONTEXT);
78
+ return;
79
+ }
80
+ if (account?.auth === "oauth" && !login) throw new Error(`${id} needs a sign-in`);
81
+ if (!login) {
82
+ if (account?.store !== "vault") throw new Error(`${id} needs an API key`);
83
+ await this.#settings.connect(id, null, given, BACKGROUND_CONTEXT);
84
+ return;
85
+ }
86
+ const answer = await this.#signIn(id, login);
87
+ if (typeof answer === "string") {
88
+ if (!mcp) throw new Error(SIGN_IN_NEEDS_VAULT);
89
+ await this.#settings.connect(id, answer, given, BACKGROUND_CONTEXT);
90
+ return;
91
+ }
92
+ if (answer?.sealed !== true) throw new Error(`${id}'s sign-in didn't finish`);
93
+ await this.#settings.connect(id, null, given, BACKGROUND_CONTEXT);
77
94
  }
78
95
  async #signIn(id, login) {
79
96
  const controller = new AbortController();
@@ -112,6 +129,7 @@ class SettingsAdapter extends Emitter {
112
129
  }
113
130
  export {
114
131
  SETTINGS_KEY,
132
+ SIGN_IN_NEEDS_VAULT,
115
133
  SettingsAdapter
116
134
  };
117
135
  //# sourceMappingURL=settings-port.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/spectrum/settings-port.ts"],
4
- "sourcesContent": ["import type {\n Account,\n ModelOption,\n Settings,\n SettingsEvents,\n SettingsPort,\n} from '@ai-ecoverse/slicc-spectrum/ui';\nimport { BACKGROUND_CONTEXT } from '@earendil-works/chord/context';\nimport type { AgentSettings, SettingsState, SignIn } from '../services.ts';\nimport type { AgentAdapter } from './agent-port.ts';\nimport { attempt } from './attempt.ts';\nimport { Emitter } from './emitter.ts';\nimport { mcpLogin } from './mcp-login.ts';\n\nexport const SETTINGS_KEY = 'slicc-agent.settings';\n\nconst defaults: Settings = {\n color: 'system',\n model: '',\n thinking: 'off',\n sendOnEnter: true,\n showThinking: false,\n diffStyle: 'unified',\n};\n\ntype Local = Omit<Settings, 'model' | 'thinking'>;\n\nexport type Login = (\n providerId: string,\n signIn: () => Promise<SignIn | null>,\n options: { signal: AbortSignal }\n) => Promise<string>;\n\nexport class SettingsAdapter extends Emitter<SettingsEvents> implements SettingsPort {\n readonly #settings: AgentSettings;\n readonly #agent: AgentAdapter;\n readonly #storage: Pick<Storage, 'getItem' | 'setItem'> | null;\n readonly #login: Login | null;\n readonly #mcpLogin: Login;\n readonly #signing = new Map<string, AbortController>();\n #local: Local;\n\n constructor(\n settings: AgentSettings,\n agent: AgentAdapter,\n storage: Pick<Storage, 'getItem' | 'setItem'> | null,\n login: Login | null = null,\n mcp: Login = mcpLogin() as Login\n ) {\n super();\n this.#mcpLogin = mcp;\n this.#settings = settings;\n this.#agent = agent;\n this.#storage = storage;\n this.#login = login;\n const saved = JSON.parse(storage?.getItem(SETTINGS_KEY) ?? '{}') as Partial<Local>;\n const { model: _model, thinking: _thinking, ...local } = { ...defaults, ...saved };\n this.#local = local;\n settings.state.subscribe(() => {\n this.emit('accounts', this.accounts());\n this.emit('settings', this.get());\n });\n agent.on('agents', () => this.emit('settings', this.get()));\n }\n\n #state(): SettingsState {\n return this.#settings.state.value ?? { models: [], accounts: [] };\n }\n\n get(): Settings {\n const cone = this.#agent.list()[0];\n return { ...this.#local, model: cone?.model ?? '', thinking: cone?.thinking ?? 'off' };\n }\n\n update(patch: Partial<Settings>): void {\n const { model, thinking, ...local } = patch;\n const id = this.#agent.active();\n if (model !== undefined) this.#agent.setModel(id, model);\n if (thinking !== undefined) this.#agent.setThinking(id, thinking);\n this.#local = { ...this.#local, ...local };\n this.#storage?.setItem(SETTINGS_KEY, JSON.stringify(this.#local));\n this.emit('settings', this.get());\n }\n\n models(): readonly ModelOption[] {\n return this.#state().models.map(({ id, label, provider, kind, reasoning, images }) => ({\n id,\n label,\n provider,\n kind,\n reasoning,\n ...(images === undefined ? {} : { images }),\n }));\n }\n\n accounts(): readonly Account[] {\n return this.#state().accounts.map(({ needs, ...account }) => {\n const shown = this.#signing.has(account.id)\n ? { ...account, status: 'signing-in' as const }\n : account;\n return needs ? { ...shown, needs } : shown;\n });\n }\n\n async connect(id: string, secret?: string, options: { region?: string } = {}): Promise<void> {\n const account = this.#state().accounts.find((candidate) => candidate.id === id);\n const login =\n account?.auth !== 'oauth' ? null : account.group === 'mcp' ? this.#mcpLogin : this.#login;\n const key = secret ?? (login ? await this.#signIn(id, login) : undefined);\n if (!key)\n throw new Error(`${id} needs ${account?.auth === 'oauth' ? 'a sign-in' : 'an API key'}`);\n await this.#settings.connect(id, key, options.region ?? null, BACKGROUND_CONTEXT);\n }\n\n async #signIn(id: string, login: Login): Promise<string> {\n const controller = new AbortController();\n this.#signing\n .get(id)\n ?.abort(new DOMException('A newer sign-in replaced this one.', 'AbortError'));\n this.#signing.set(id, controller);\n this.emit('accounts', this.accounts());\n try {\n const key = await login(\n id,\n () => this.#settings.signIn(id, BACKGROUND_CONTEXT) as Promise<SignIn | null>,\n {\n signal: controller.signal,\n }\n );\n controller.signal.throwIfAborted();\n return key;\n } finally {\n if (this.#signing.get(id) === controller) this.#signing.delete(id);\n this.emit('accounts', this.accounts());\n }\n }\n\n cancel(id: string): void {\n const controller = this.#signing.get(id);\n if (!controller) return;\n this.#signing.delete(id);\n controller.abort(new DOMException('The sign-in was cancelled.', 'AbortError'));\n this.emit('accounts', this.accounts());\n }\n\n disconnect(id: string): void {\n attempt(this.#settings.disconnect(id, BACKGROUND_CONTEXT), 'disconnect accounts', (text) =>\n this.#agent.notify(text)\n );\n }\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import type {\n Account,\n ModelOption,\n Settings,\n SettingsEvents,\n SettingsPort,\n} from '@ai-ecoverse/slicc-spectrum/ui';\nimport { BACKGROUND_CONTEXT } from '@earendil-works/chord/context';\nimport type { AgentSettings, SettingsState, SignIn } from '../services.ts';\nimport type { AgentAdapter } from './agent-port.ts';\nimport { attempt } from './attempt.ts';\nimport { Emitter } from './emitter.ts';\nimport { mcpLogin } from './mcp-login.ts';\n\nexport const SETTINGS_KEY = 'slicc-agent.settings';\n\nconst defaults: Settings = {\n color: 'system',\n model: '',\n thinking: 'off',\n sendOnEnter: true,\n showThinking: false,\n diffStyle: 'unified',\n};\n\ntype Local = Omit<Settings, 'model' | 'thinking'>;\n\nexport type Sealed = { sealed: true };\n\nexport type Login = (\n providerId: string,\n signIn: () => Promise<SignIn | null>,\n options: { signal: AbortSignal }\n) => Promise<string | Sealed>;\n\nexport const SIGN_IN_NEEDS_VAULT = \"Adobe sign-in needs seven's vault: update seven\";\n\nexport class SettingsAdapter extends Emitter<SettingsEvents> implements SettingsPort {\n readonly #settings: AgentSettings;\n readonly #agent: AgentAdapter;\n readonly #storage: Pick<Storage, 'getItem' | 'setItem'> | null;\n readonly #login: Login | null;\n readonly #mcpLogin: Login;\n readonly #signing = new Map<string, AbortController>();\n #local: Local;\n\n constructor(\n settings: AgentSettings,\n agent: AgentAdapter,\n storage: Pick<Storage, 'getItem' | 'setItem'> | null,\n login: Login | null = null,\n mcp: Login = mcpLogin() as Login\n ) {\n super();\n this.#mcpLogin = mcp;\n this.#settings = settings;\n this.#agent = agent;\n this.#storage = storage;\n this.#login = login;\n const saved = JSON.parse(storage?.getItem(SETTINGS_KEY) ?? '{}') as Partial<Local>;\n const { model: _model, thinking: _thinking, ...local } = { ...defaults, ...saved };\n this.#local = local;\n settings.state.subscribe(() => {\n this.emit('accounts', this.accounts());\n this.emit('settings', this.get());\n });\n agent.on('agents', () => this.emit('settings', this.get()));\n }\n\n #state(): SettingsState {\n return this.#settings.state.value ?? { models: [], accounts: [] };\n }\n\n get(): Settings {\n const cone = this.#agent.list()[0];\n return { ...this.#local, model: cone?.model ?? '', thinking: cone?.thinking ?? 'off' };\n }\n\n update(patch: Partial<Settings>): void {\n const { model, thinking, ...local } = patch;\n const id = this.#agent.active();\n if (model !== undefined) this.#agent.setModel(id, model);\n if (thinking !== undefined) this.#agent.setThinking(id, thinking);\n this.#local = { ...this.#local, ...local };\n this.#storage?.setItem(SETTINGS_KEY, JSON.stringify(this.#local));\n this.emit('settings', this.get());\n }\n\n models(): readonly ModelOption[] {\n return this.#state().models.map(({ id, label, provider, kind, reasoning, images }) => ({\n id,\n label,\n provider,\n kind,\n reasoning,\n ...(images === undefined ? {} : { images }),\n }));\n }\n\n accounts(): readonly Account[] {\n return this.#state().accounts.map(({ needs, ...account }) => {\n const shown = this.#signing.has(account.id)\n ? { ...account, status: 'signing-in' as const }\n : account;\n return needs ? { ...shown, needs } : shown;\n });\n }\n\n async connect(id: string, secret?: string, fields?: Record<string, string>): Promise<void> {\n const account = this.#state().accounts.find((candidate) => candidate.id === id);\n const mcp = account?.group === 'mcp';\n const login = account?.auth !== 'oauth' ? null : mcp ? this.#mcpLogin : this.#login;\n const given = fields ? { ...fields } : null;\n if (secret !== undefined) {\n await this.#settings.connect(id, secret, given, BACKGROUND_CONTEXT);\n return;\n }\n if (account?.auth === 'oauth' && !login) throw new Error(`${id} needs a sign-in`);\n if (!login) {\n if (account?.store !== 'vault') throw new Error(`${id} needs an API key`);\n await this.#settings.connect(id, null, given, BACKGROUND_CONTEXT);\n return;\n }\n const answer = await this.#signIn(id, login);\n if (typeof answer === 'string') {\n if (!mcp) throw new Error(SIGN_IN_NEEDS_VAULT);\n await this.#settings.connect(id, answer, given, BACKGROUND_CONTEXT);\n return;\n }\n if (answer?.sealed !== true) throw new Error(`${id}'s sign-in didn't finish`);\n await this.#settings.connect(id, null, given, BACKGROUND_CONTEXT);\n }\n\n async #signIn(id: string, login: Login): Promise<string | Sealed> {\n const controller = new AbortController();\n this.#signing\n .get(id)\n ?.abort(new DOMException('A newer sign-in replaced this one.', 'AbortError'));\n this.#signing.set(id, controller);\n this.emit('accounts', this.accounts());\n try {\n const key = await login(\n id,\n () => this.#settings.signIn(id, BACKGROUND_CONTEXT) as Promise<SignIn | null>,\n {\n signal: controller.signal,\n }\n );\n controller.signal.throwIfAborted();\n return key;\n } finally {\n if (this.#signing.get(id) === controller) this.#signing.delete(id);\n this.emit('accounts', this.accounts());\n }\n }\n\n cancel(id: string): void {\n const controller = this.#signing.get(id);\n if (!controller) return;\n this.#signing.delete(id);\n controller.abort(new DOMException('The sign-in was cancelled.', 'AbortError'));\n this.emit('accounts', this.accounts());\n }\n\n disconnect(id: string): void {\n attempt(this.#settings.disconnect(id, BACKGROUND_CONTEXT), 'disconnect accounts', (text) =>\n this.#agent.notify(text)\n );\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -46,7 +46,7 @@ export declare function hostAgent(agent: Agent, options?: {
46
46
  changes?: ChangesRuntime;
47
47
  mcp?: Pick<McpRuntime, 'close'>;
48
48
  users?: UserClients;
49
- monitor?: Pick<MonitorOptions, 'kernel' | 'groups' | 'users' | 'secrets'>;
49
+ monitor?: Pick<MonitorOptions, 'kernel' | 'groups' | 'users'>;
50
50
  pages?: Pages;
51
51
  secrets?: HostSecrets;
52
52
  uploads?: Uploads;
@@ -3,7 +3,6 @@ export { type Agent, type AgentOptions, answerText, openAgent } from './agent.ts
3
3
  export { FILE_LIMIT, IMAGE_LIMIT, type SendAttachment, type ShownAttachment, splitUser, TOTAL_LIMIT, userParts, } from './attachments.ts';
4
4
  export { type AgentConnection, connectAgent } from './client.ts';
5
5
  export { createAgentControl } from './control.ts';
6
- export { CREDENTIALS_DATABASE, EncryptedCredentialStore } from './credentials.ts';
7
6
  export { type AgentHost, type ConnectOptions, hostAgent } from './host.ts';
8
7
  export type { KernelClient, KernelFs, KernelProcess, KernelStat, SpawnOptions, } from './kernel/client.ts';
9
8
  export { HOME, type KernelEnvOptions, kernelEnvironment, SliccKernelEnv } from './kernel/env.ts';
@@ -1,4 +1,4 @@
1
- import type { CredentialStore, Provider } from '@earendil-works/pi-ai';
1
+ import type { Provider } from '@earendil-works/pi-ai';
2
2
  import type { Models } from '@earendil-works/pi-ai/models';
3
3
  import { type ModelRef, type Storage } from '@earendil-works/pi-durable';
4
4
  import { type AgentHost } from './host.ts';
@@ -6,6 +6,9 @@ import type { KernelClient } from './kernel/client.ts';
6
6
  import { type UserClients } from './kernel/users.ts';
7
7
  import { type Transport } from './net.ts';
8
8
  import { type Assets } from './scoops/index.ts';
9
+ import { type ModelBases } from './secrets/endpoints.ts';
10
+ import { type PlainStore } from './secrets/store.ts';
11
+ import { createSliccModels } from './settings.ts';
9
12
  import { type WorkerScope } from './worker.ts';
10
13
  export interface AgentWorkerScope extends WorkerScope {
11
14
  fetch: typeof fetch;
@@ -20,7 +23,7 @@ export interface AgentWorkerOptions {
20
23
  model?: ModelRef;
21
24
  providers?: Provider[];
22
25
  attach?: KernelAttach;
23
- credentials?: () => Promise<CredentialStore>;
26
+ store?: () => Promise<PlainStore>;
24
27
  storage?: () => Promise<Storage>;
25
28
  assets?: Assets;
26
29
  codemodeWasm?: () => Promise<WebAssembly.Module | undefined>;
@@ -31,7 +34,9 @@ export interface AgentWorkerOptions {
31
34
  }
32
35
  export declare function usersOf(admin: MessagePort | undefined, wanted: boolean | undefined, attach: KernelAttach): UserClients | undefined;
33
36
  export declare const STORE_DIR = "/.slicc";
37
+ export declare const ACCOUNTS_FILE = "/.slicc/accounts.json";
34
38
  export declare function seesImages(models: Pick<Models, 'getModel'>, ref: ModelRef | undefined): boolean;
35
39
  export declare const MCP_CALLBACK = "/oauth/mcp-callback";
40
+ export declare function modelBases(providers: readonly Provider[], models: Pick<ReturnType<typeof createSliccModels>, 'getModels'>): ModelBases[];
36
41
  export declare function alive(client: KernelClient): (pid: number) => Promise<boolean>;
37
42
  export declare function runAgentWorker(scope: AgentWorkerScope, options?: AgentWorkerOptions): Promise<AgentHost>;
@@ -1,20 +1,26 @@
1
- import type { CredentialStore } from '@earendil-works/pi-ai';
1
+ import type { Context } from '@earendil-works/chord';
2
2
  import type { McpFetch } from '@earendil-works/pi-mcp';
3
3
  import type { AccountState } from '../services.ts';
4
4
  import type { McpCatalog } from './catalog.ts';
5
5
  import type { McpServerEntry } from './config.ts';
6
6
  import type { McpServerConnection } from './connection.ts';
7
+ import { type McpRecords } from './credentials.ts';
7
8
  import { type McpSignIn, type StoredOAuth } from './oauth.ts';
9
+ export declare const TOKENS_IN_VAULT = "MCP tokens are kept in seven's vault: update seven";
8
10
  export interface McpAccounts {
9
11
  accounts(): Promise<AccountState[]>;
10
12
  signIn(id: string): Promise<McpSignIn>;
11
- connect(id: string, secret: string): Promise<void>;
13
+ connect(id: string, secret: string | null): Promise<void>;
12
14
  disconnect(id: string): Promise<void>;
13
15
  onChange(listener: () => void): () => void;
14
16
  }
15
17
  export interface AccountSources {
16
- credentials: CredentialStore;
18
+ records: McpRecords & {
19
+ refresh(context: Context): Promise<void>;
20
+ };
17
21
  oauth: (entry: McpServerEntry) => StoredOAuth;
18
- fetch: McpFetch;
22
+ fetch: (server: string) => McpFetch;
23
+ grant: (server: string) => McpFetch;
24
+ register: (server: string, tokenUrl: string) => Promise<void>;
19
25
  }
20
26
  export declare function mcpAccounts(catalog: McpCatalog, sources: AccountSources, restart: (connection: McpServerConnection) => void, listeners: Set<() => void>): McpAccounts;
@@ -3,7 +3,6 @@ import { type McpServerEntry } from './config.ts';
3
3
  export type ServerState = 'connecting' | 'connected' | 'needs-auth' | 'needs-secret' | 'failed' | 'closed';
4
4
  export type TransportFactory = (entry: McpServerEntry) => Promise<{
5
5
  transport: McpTransport;
6
- secrets: string[];
7
6
  } | {
8
7
  missing: string[];
9
8
  }>;
@@ -36,7 +35,6 @@ export declare class McpServerConnection {
36
35
  resources: Resource[];
37
36
  resourceTemplates: ResourceTemplate[];
38
37
  instructions: string | undefined;
39
- secrets: string[];
40
38
  constructor(options: ConnectionOptions);
41
39
  get name(): string;
42
40
  get timeoutMs(): number;
@@ -1,15 +1,17 @@
1
- import type { CredentialStore } from '@earendil-works/pi-ai';
2
1
  import { type McpServerConfig } from './config.ts';
3
2
  export declare const MCP_CREDENTIAL_PREFIX = "mcp:";
3
+ export interface McpRecords {
4
+ mcp(server: string, name?: string): {
5
+ placeholder: string;
6
+ } | undefined;
7
+ }
4
8
  export declare function credentialKey(server: string, url: string): Promise<string>;
5
9
  export declare function secretNames(config: McpServerConfig): string[];
6
10
  export type Resolved = {
7
11
  ok: true;
8
12
  headers: Record<string, string>;
9
- secrets: string[];
10
13
  } | {
11
14
  ok: false;
12
15
  missing: string[];
13
16
  };
14
- export declare function resolveHeaders(server: string, config: McpServerConfig, credentials: CredentialStore): Promise<Resolved>;
15
- export declare function scrub(text: string, secrets: readonly string[]): string;
17
+ export declare function resolveHeaders(server: string, config: McpServerConfig, records: McpRecords): Resolved;
@@ -1,6 +1,6 @@
1
- import type { CredentialStore } from '@earendil-works/pi-ai';
2
1
  import type { AuthProvider, McpFetch } from '@earendil-works/pi-mcp';
3
2
  import { authorizeMcp, McpOAuthAuthorizationRequiredError, type McpOAuthState } from '@earendil-works/pi-mcp/oauth';
3
+ import type { PlainStore } from '../secrets/store.ts';
4
4
  import type { McpSignIn } from '../services.ts';
5
5
  import type { McpServerConfig } from './config.ts';
6
6
  type Provider = Parameters<typeof authorizeMcp>[0];
@@ -25,7 +25,7 @@ export declare class StoredOAuth implements Provider {
25
25
  #private;
26
26
  readonly redirectUrl: string;
27
27
  readonly clientMetadata: Provider['clientMetadata'];
28
- constructor(server: OAuthServer, credentials: CredentialStore, redirectUrl: string);
28
+ constructor(server: OAuthServer, store: PlainStore, redirectUrl: string);
29
29
  get serverUrl(): string;
30
30
  load(): Promise<McpOAuthState>;
31
31
  update(change: (state: McpOAuthState) => McpOAuthState): Promise<void>;
@@ -47,6 +47,7 @@ export type { McpSignIn } from '../services.ts';
47
47
  export declare function beginSignIn(provider: StoredOAuth, server: OAuthServer, options: {
48
48
  fetch: McpFetch;
49
49
  resourceMetadataUrl?: URL;
50
+ register(tokenUrl: string): Promise<void>;
50
51
  }): Promise<McpSignIn>;
51
52
  export interface Callback {
52
53
  code?: string;
@@ -1,20 +1,35 @@
1
1
  import type { Context } from '@earendil-works/chord';
2
- import type { CredentialStore } from '@earendil-works/pi-ai';
3
2
  import type { Registry } from '@earendil-works/pi-durable';
4
3
  import type { ExecutionEnv } from '@earendil-works/pi-durable/env';
5
4
  import type { LickEvent, Licks } from '../licks/licks.ts';
5
+ import type { McpServerSource } from '../secrets/endpoints.ts';
6
+ import type { PlainStore } from '../secrets/store.ts';
6
7
  import { type McpAccounts } from './accounts.ts';
7
8
  import { McpCatalog } from './catalog.ts';
8
9
  import { type McpConfigProblem } from './config.ts';
9
10
  import { McpServerConnection } from './connection.ts';
11
+ import { type McpRecords } from './credentials.ts';
10
12
  export declare const MCP_LOG_MAX_BYTES: number;
11
13
  export { configPath, logPath, shown } from './paths.ts';
14
+ export interface McpVault {
15
+ records: McpRecords & {
16
+ refresh(context: Context): Promise<void>;
17
+ state: {
18
+ subscribe(listener: () => void): () => void;
19
+ };
20
+ };
21
+ fetch(server: string, base: typeof fetch): typeof fetch;
22
+ grant(server: string, base: typeof fetch): typeof fetch;
23
+ servers(list: readonly McpServerSource[]): Promise<void>;
24
+ token(server: string, url: string): Promise<void>;
25
+ }
12
26
  export interface McpAttach {
13
27
  licks: Licks;
14
28
  env: ExecutionEnv;
15
29
  home: string;
16
30
  agentDir?: string;
17
- credentials: CredentialStore;
31
+ store: PlainStore;
32
+ vault: McpVault;
18
33
  fetch: typeof fetch;
19
34
  version: string;
20
35
  reloadMs: number;
@@ -31,14 +46,13 @@ export interface ServerStatus {
31
46
  export type { McpAccounts } from './accounts.ts';
32
47
  export interface McpRuntime extends McpAccounts {
33
48
  status(): ServerStatus[];
34
- secrets(): string[];
35
49
  reload(context: Context): Promise<void>;
36
50
  close(context: Context): Promise<void>;
37
51
  }
38
52
  export declare function problemLick(problem: McpConfigProblem, home: string, dir?: string): LickEvent;
39
53
  export declare function stateLick(connection: McpServerConnection, cors: boolean): LickEvent | undefined;
40
54
  export declare function connectedLick(connection: McpServerConnection): LickEvent;
41
- export declare function logLine(server: string, params: unknown, secrets: readonly string[], at: Date): string;
55
+ export declare function logLine(server: string, params: unknown, at: Date): string;
42
56
  export declare function attachMcp(catalog: McpCatalog, options: McpAttach, context: Context): Promise<McpRuntime>;
43
57
  export declare function startMcp(registry: Registry, options: McpAttach, context: Context): Promise<{
44
58
  catalog: McpCatalog;
@@ -11,6 +11,8 @@ export interface ModelsOptions {
11
11
  agents: Agents;
12
12
  settings: Pick<AgentSettings, 'state'>;
13
13
  catalog: Pick<Models, 'getProviders' | 'getModels'>;
14
+ locked?: () => boolean;
14
15
  }
16
+ export declare const LOCKED_NOTE = "the vault is locked: unlock it to use these accounts";
15
17
  export declare function closest(wanted: string, ids: readonly string[], count?: number): string[];
16
18
  export declare function modelsCommand(options: ModelsOptions): (argv: readonly string[], caller: string | null, context: Context) => Promise<Answer>;
@@ -47,7 +47,6 @@ export interface MonitorOptions {
47
47
  name: string;
48
48
  uid: number;
49
49
  }[]>;
50
- secrets?: () => readonly string[];
51
50
  now?: () => number;
52
51
  timers?: Timers;
53
52
  ttlMs?: number;
@@ -1,5 +1,5 @@
1
1
  export declare const TEXT_MAX = 160;
2
2
  export declare function cut(text: string, max?: number): string;
3
- export declare function redacted(text: string, secrets: readonly string[]): string;
4
- export declare function commandLine(argv: readonly string[], secrets: readonly string[]): string;
3
+ export declare function redacted(text: string): string;
4
+ export declare function commandLine(argv: readonly string[]): string;
5
5
  export declare function program(argv: readonly string[]): string;
@@ -0,0 +1,5 @@
1
+ import type { CredentialStore } from '@earendil-works/pi-ai';
2
+ import type { VaultRecords } from './records.ts';
3
+ export declare const KEYS_IN_VAULT = "model keys are kept in seven's vault: enter them in Settings \u203A Accounts";
4
+ export type FieldsOf = (providerId: string) => Readonly<Record<string, string>> | undefined;
5
+ export declare function vaultCredentials(records: Pick<VaultRecords, 'model' | 'state'>, env?: FieldsOf): CredentialStore;
@@ -0,0 +1,27 @@
1
+ import type { McpServerEntry, ModelEndpoint } from '@ai-ecoverse/slicc-vault';
2
+ import type { ModelRoute } from './fetch.ts';
3
+ import type { AgentRecord } from './records.ts';
4
+ import type { Vault } from './vault.ts';
5
+ export declare const BEDROCK_ENDPOINTS: string[];
6
+ export declare function modelUrl(raw: string): boolean;
7
+ export declare function mcpUrl(raw: string): boolean;
8
+ export declare function pattern(base: string): RegExp;
9
+ export interface ModelBases {
10
+ provider: string;
11
+ urls: readonly string[];
12
+ }
13
+ export declare function modelRoute(bases: () => readonly ModelBases[], records: () => readonly AgentRecord[]): ModelRoute;
14
+ export declare function modelEndpoints(bases: readonly ModelBases[]): ModelEndpoint[];
15
+ export interface McpServerSource {
16
+ server: string;
17
+ url: string;
18
+ names: readonly string[];
19
+ }
20
+ export declare function mcpEndpoints(servers: readonly McpServerSource[], tokens: ReadonlyMap<string, string>): McpServerEntry[];
21
+ export interface Endpoints {
22
+ models(bases: readonly ModelBases[]): Promise<void>;
23
+ servers(servers: readonly McpServerSource[]): Promise<void>;
24
+ token(server: string, url: string): Promise<void>;
25
+ close(): void;
26
+ }
27
+ export declare function vaultEndpoints(vault: Pick<Vault, 'state' | 'connected' | 'endpoints'>): Endpoints;