@ai-ecoverse/slicc-agent 3.52.1 → 4.1.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.
- package/README.md +17 -13
- package/dist/client.js +3 -1
- package/dist/client.js.map +2 -2
- package/dist/control.js +4 -1
- package/dist/control.js.map +2 -2
- package/dist/freezer/index.js +27 -68
- package/dist/freezer/index.js.map +2 -2
- package/dist/host.js +2 -0
- package/dist/host.js.map +2 -2
- package/dist/index.js +0 -3
- package/dist/index.js.map +2 -2
- package/dist/kernel/agent-users.js +3 -0
- package/dist/kernel/agent-users.js.map +2 -2
- package/dist/main.js +111 -26
- package/dist/main.js.map +2 -2
- package/dist/mcp/accounts.js +18 -14
- package/dist/mcp/accounts.js.map +2 -2
- package/dist/mcp/connection.js +0 -2
- package/dist/mcp/connection.js.map +2 -2
- package/dist/mcp/credentials.js +6 -15
- package/dist/mcp/credentials.js.map +2 -2
- package/dist/mcp/index.js +0 -1
- package/dist/mcp/index.js.map +2 -2
- package/dist/mcp/oauth.js +15 -20
- package/dist/mcp/oauth.js.map +2 -2
- package/dist/mcp/runtime.js +36 -14
- package/dist/mcp/runtime.js.map +2 -2
- package/dist/mcp/tools.js +4 -6
- package/dist/mcp/tools.js.map +2 -2
- package/dist/models/index.js +7 -4
- package/dist/models/index.js.map +2 -2
- package/dist/monitor/index.js +5 -10
- package/dist/monitor/index.js.map +2 -2
- package/dist/monitor/redact.js +4 -5
- package/dist/monitor/redact.js.map +2 -2
- package/dist/secrets/credentials.js +32 -0
- package/dist/secrets/credentials.js.map +7 -0
- package/dist/secrets/endpoints.js +111 -0
- package/dist/secrets/endpoints.js.map +7 -0
- package/dist/secrets/extension.js +6 -3
- package/dist/secrets/extension.js.map +2 -2
- package/dist/secrets/fetch.js +160 -0
- package/dist/secrets/fetch.js.map +7 -0
- package/dist/secrets/records.js +35 -0
- package/dist/secrets/records.js.map +7 -0
- package/dist/secrets/store.js +50 -0
- package/dist/secrets/store.js.map +7 -0
- package/dist/secrets/vault.js +58 -13
- package/dist/secrets/vault.js.map +2 -2
- package/dist/services.js.map +2 -2
- package/dist/settings.js +85 -23
- package/dist/settings.js.map +2 -2
- package/dist/skills/index.js +20 -3
- package/dist/skills/index.js.map +3 -3
- package/dist/spectrum/agent-port.js +29 -1
- package/dist/spectrum/agent-port.js.map +2 -2
- package/dist/spectrum/settings-port.js +24 -6
- package/dist/spectrum/settings-port.js.map +2 -2
- package/dist/titles/extension.js +110 -0
- package/dist/titles/extension.js.map +7 -0
- package/dist/{freezer/title.js → titles/generate.js} +21 -2
- package/dist/titles/generate.js.map +7 -0
- package/dist/types/client.d.ts +2 -1
- package/dist/types/control.d.ts +1 -1
- package/dist/types/freezer/index.d.ts +2 -5
- package/dist/types/host.d.ts +1 -1
- package/dist/types/index.d.ts +0 -1
- package/dist/types/main.d.ts +7 -2
- package/dist/types/mcp/accounts.d.ts +10 -4
- package/dist/types/mcp/connection.d.ts +0 -2
- package/dist/types/mcp/credentials.d.ts +6 -4
- package/dist/types/mcp/oauth.d.ts +3 -2
- package/dist/types/mcp/runtime.d.ts +18 -4
- package/dist/types/models/index.d.ts +2 -0
- package/dist/types/monitor/index.d.ts +0 -1
- package/dist/types/monitor/redact.d.ts +2 -2
- package/dist/types/secrets/credentials.d.ts +5 -0
- package/dist/types/secrets/endpoints.d.ts +27 -0
- package/dist/types/secrets/fetch.d.ts +13 -0
- package/dist/types/secrets/records.d.ts +13 -0
- package/dist/types/secrets/store.d.ts +7 -0
- package/dist/types/secrets/vault.d.ts +31 -1
- package/dist/types/services.d.ts +13 -1
- package/dist/types/settings.d.ts +17 -2
- package/dist/types/skills/index.d.ts +4 -1
- package/dist/types/spectrum/agent-port.d.ts +1 -1
- package/dist/types/spectrum/settings-port.d.ts +6 -4
- package/dist/types/titles/extension.d.ts +19 -0
- package/dist/types/{freezer/title.d.ts → titles/generate.d.ts} +4 -0
- package/package.json +6 -4
- package/dist/credentials.js +0 -100
- package/dist/credentials.js.map +0 -7
- package/dist/freezer/title.js.map +0 -7
- package/dist/types/credentials.d.ts +0 -12
package/dist/mcp/tools.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/mcp/tools.ts"],
|
|
4
|
-
"sourcesContent": ["import type { Context, JsonValue } from '@earendil-works/chord';\nimport {\n type CodemodeJsonSchema,\n type CodemodeTool,\n renderToolSample,\n toCodemodeIdentifier,\n} from '@earendil-works/pi-codemode';\nimport {\n defineTool,\n type ToolExecutionApi,\n type ToolRegistration,\n} from '@earendil-works/pi-durable';\nimport type { McpRequestOptions, Tool as McpTool } from '@earendil-works/pi-mcp';\nimport { scrubbedOutput } from '../secrets/scrub.ts';\nimport type { McpExposure } from './config.ts';\nimport { errorMessage, type McpServerConnection } from './connection.ts';\nimport {\n type Content,\n convertResult,\n limitContent,\n modelContent,\n READ_MCP_RESOURCE,\n type Saver,\n scriptResult,\n spiller,\n} from './content.ts';\nimport { scrub } from './credentials.ts';\n\nexport const LIST_MCP_RESOURCES = 'list_mcp_resources';\nexport const LIST_MCP_RESOURCE_TEMPLATES = 'list_mcp_resource_templates';\nexport { READ_MCP_RESOURCE };\n\nexport interface McpToolEntry {\n server: string;\n name: string;\n exposure: McpExposure;\n tool: McpTool;\n connection: McpServerConnection;\n}\n\nexport type McpDetails = { server: string; tool: string; fullOutputPath?: string };\n\nfunction parametersOf(schema: Record<string, unknown>): Record<string, unknown> {\n const { $schema: _schema, ...rest } = schema;\n return {\n ...rest,\n type: rest.type ?? 'object',\n ...(rest.properties === undefined ? { properties: {} } : {}),\n };\n}\n\nexport function resultSchema(structured: Record<string, unknown> | undefined): CodemodeJsonSchema {\n return {\n type: 'object',\n properties: {\n content: { type: 'array', items: { type: 'object' } },\n ...(structured ? { structuredContent: structured } : {}),\n isError: { type: 'boolean' },\n },\n required: ['content'],\n };\n}\n\nfunction describe(entry: McpToolEntry): string {\n const title = entry.tool.title ?? entry.tool.annotations?.title;\n return (\n entry.tool.description?.trim() ||\n title ||\n `MCP tool ${entry.tool.name} from server ${entry.server}`\n );\n}\n\nfunction signalOf(context: Context): AbortSignal | undefined {\n return context.abortSignal as AbortSignal | undefined;\n}\n\nexport function apiSaver(api: ToolExecutionApi, prefix: string, context: Context): Saver {\n let counter = 0;\n return spiller(\n async (path, data, using) => (await api.env?.writeFile(path, data, using))?.ok === true,\n () => `${api.callId}-${prefix}${++counter}`,\n context\n );\n}\n\nfunction progressText(progress: { progress: number; total?: number; message?: string }): string {\n const total = progress.total === undefined ? '' : `/${progress.total}`;\n return progress.message ?? `Progress ${progress.progress}${total}`;\n}\n\nfunction failure(entry: { connection: McpServerConnection }, error: unknown): never {\n const message = error instanceof Error ? error.message : String(error);\n throw new Error(scrub(message, entry.connection.secrets));\n}\n\nexport function directTool(entry: McpToolEntry, readable: () => boolean): ToolRegistration {\n return defineTool({\n name: entry.name,\n description: describe(entry),\n parameters: parametersOf(entry.tool.inputSchema) as never,\n replay: 'unsafe',\n async execute(args, api, context) {\n const save = apiSaver(api, '', context);\n const options: McpRequestOptions = {\n timeoutMs: entry.connection.timeoutMs,\n onProgress: (progress) => void scrubbedOutput(api, `${progressText(progress)}\\n`),\n };\n const signal = signalOf(context);\n if (signal) options.signal = signal;\n const result = await entry.connection\n .callTool(entry.tool.name, args as Record<string, unknown>, options)\n .catch((error) => failure(entry, error));\n const converted = await convertResult(\n entry.server,\n entry.tool.name,\n result,\n save,\n readable()\n );\n const details: McpDetails = {\n server: entry.server,\n tool: entry.tool.name,\n ...(converted.fullOutputPath ? { fullOutputPath: converted.fullOutputPath } : {}),\n };\n return {\n content: converted.content,\n details: details as JsonValue,\n ...(converted.isError ? { isError: true } : {}),\n };\n },\n }) as ToolRegistration;\n}\n\nexport function scriptTool(entry: McpToolEntry, signal: AbortSignal | undefined): CodemodeTool {\n const inputSchema = parametersOf(entry.tool.inputSchema);\n const outputSchema = resultSchema(entry.tool.outputSchema as Record<string, unknown> | undefined);\n return {\n name: entry.name,\n description: describe(entry),\n inputSchema,\n outputSchema,\n async execute(args, { signal: own }) {\n const combined = signal ? AbortSignal.any([own, signal]) : own;\n const result = await entry.connection\n .callTool(entry.tool.name, (args ?? {}) as Record<string, unknown>, {\n signal: combined,\n timeoutMs: entry.connection.timeoutMs,\n })\n .catch((error) => failure(entry, error));\n return scriptResult(result);\n },\n };\n}\n\nexport interface ResourceServer {\n name: string;\n connection: McpServerConnection;\n}\n\nfunction stringArgument(params: unknown, key: string): string | undefined {\n const value = (params as Record<string, unknown> | undefined)?.[key];\n if (value === undefined || value === null) return undefined;\n if (typeof value !== 'string') throw new Error(`${key} must be a string`);\n return value.trim() || undefined;\n}\n\nfunction listed(server: string, item: object): Record<string, unknown> {\n const { _meta, icons: _icons, ...rest } = item as Record<string, unknown>;\n return { server, ...rest };\n}\n\nconst stringProperty = (description: string) => ({ type: 'string', description });\nconst LIST_PARAMETERS = {\n type: 'object',\n properties: {\n server: stringProperty('MCP server name. Omit to list every server with resources.'),\n cursor: stringProperty(\n 'Opaque cursor from a previous call with the same server; omit for the first page.'\n ),\n },\n additionalProperties: false,\n};\nconst READ_PARAMETERS = {\n type: 'object',\n properties: {\n server: stringProperty(\n \"MCP server name exactly as configured. Must match the 'server' field returned by list_mcp_resources.\"\n ),\n uri: stringProperty(\n 'Resource URI to read. Must be one of the URIs returned by list_mcp_resources.'\n ),\n },\n required: ['server', 'uri'],\n additionalProperties: false,\n};\n\nconst DESCRIPTIONS: Record<string, string> = {\n [LIST_MCP_RESOURCES]:\n 'Lists resources provided by MCP servers. Resources allow servers to share data that provides context to language models, such as files, database schemas, or application-specific information. Prefer resources over web search when possible.',\n [LIST_MCP_RESOURCE_TEMPLATES]:\n 'Lists resource templates provided by MCP servers. Parameterized resource templates allow servers to share data that takes parameters and provides context to language models, such as files, database schemas, or application-specific information. Prefer resource templates over web search when possible.',\n [READ_MCP_RESOURCE]:\n 'Read a specific resource from an MCP server given the server name and resource URI.',\n};\n\ntype Key = 'resources' | 'resourceTemplates';\n\nfunction find(servers: readonly ResourceServer[], name: string): ResourceServer {\n const server = servers.find((candidate) => candidate.name === name);\n if (server) return server;\n const available = servers.map((candidate) => candidate.name).join(', ');\n throw new Error(\n `MCP server \"${name}\" has no resources${available ? `. Servers with resources: ${available}` : ''}`\n );\n}\n\nasync function listing(\n servers: readonly ResourceServer[],\n params: unknown,\n signal: AbortSignal | undefined,\n key: Key\n): Promise<Record<string, unknown>> {\n const serverName = stringArgument(params, 'server');\n const cursor = stringArgument(params, 'cursor');\n const visible = (item: object) => {\n const { uri, uriTemplate, mimeType } = item as Record<string, string | undefined>;\n const target = uri ?? uriTemplate ?? '';\n return !(target.startsWith('ui://') || /;\\s*profile\\s*=\\s*\"?mcp-app\"?/i.test(mimeType ?? ''));\n };\n const options = (server: ResourceServer): McpRequestOptions => ({\n timeoutMs: server.connection.timeoutMs,\n ...(signal ? { signal } : {}),\n });\n if (serverName) {\n const server = find(servers, serverName);\n const page =\n key === 'resources'\n ? await server.connection.resourcesPage(cursor, options(server)).then((result) => ({\n items: result.resources as object[],\n nextCursor: result.nextCursor,\n }))\n : await server.connection.resourceTemplatesPage(cursor, options(server)).then((result) => ({\n items: result.resourceTemplates as object[],\n nextCursor: result.nextCursor,\n }));\n return {\n server: server.name,\n [key]: page.items.filter(visible).map((item) => listed(server.name, item)),\n ...(page.nextCursor === undefined ? {} : { nextCursor: page.nextCursor }),\n };\n }\n if (cursor) throw new Error('cursor can only be used when a server is specified');\n const sorted = [...servers].sort((a, b) => a.name.localeCompare(b.name));\n const results = await Promise.allSettled(\n sorted.map((server) =>\n key === 'resources'\n ? server.connection.allResources(options(server))\n : server.connection.allResourceTemplates(options(server))\n )\n );\n const items: Record<string, unknown>[] = [];\n const errors: { server: string; error: string }[] = [];\n results.forEach((result, index) => {\n const server = (sorted[index] as ResourceServer).name;\n if (result.status === 'fulfilled')\n items.push(...(result.value as object[]).filter(visible).map((item) => listed(server, item)));\n else\n errors.push({\n server,\n error: errorMessage(result.reason),\n });\n });\n return { [key]: items, ...(errors.length ? { errors } : {}) };\n}\n\nasync function reading(\n servers: readonly ResourceServer[],\n params: unknown,\n signal: AbortSignal | undefined,\n save: Saver\n): Promise<{ content: Content[]; payload: Record<string, unknown>; fullOutputPath?: string }> {\n const serverName = stringArgument(params, 'server');\n const uri = stringArgument(params, 'uri');\n if (!serverName) throw new Error('server must be provided');\n if (!uri) throw new Error('uri must be provided');\n const server = find(servers, serverName);\n const result = await server.connection.readResource(uri, {\n timeoutMs: server.connection.timeoutMs,\n ...(signal ? { signal } : {}),\n });\n const blocks = result.contents.flatMap((contents) => [\n ...(result.contents.length > 1 ? [{ type: 'text' as const, text: `${contents.uri}:` }] : []),\n { type: 'resource' as const, resource: contents },\n ]);\n const converted = await modelContent(server.name, blocks, save);\n const limited = await limitContent(\n converted.length ? converted : [{ type: 'text', text: `Resource ${uri} is empty.` }],\n save\n );\n const contents = result.contents.map((item) => {\n const { _meta: _ignored, ...rest } = item as typeof item & { _meta?: unknown };\n return rest;\n });\n return { ...limited, payload: { server: server.name, uri, contents } };\n}\n\nexport type ServersFor = (\n api: ToolExecutionApi,\n context: Context\n) => Promise<readonly ResourceServer[]>;\n\nexport function resourceTools(servers: ServersFor): ToolRegistration[] {\n const listTool = (name: string, key: Key) =>\n defineTool({\n name,\n description: DESCRIPTIONS[name] as string,\n parameters: LIST_PARAMETERS as never,\n replay: 'safe',\n async execute(args, api, context) {\n const payload = await listing(await servers(api, context), args, signalOf(context), key);\n const limited = await limitContent(\n [{ type: 'text', text: JSON.stringify(payload) }],\n apiSaver(api, '', context)\n );\n return { content: limited.content };\n },\n }) as ToolRegistration;\n return [\n listTool(LIST_MCP_RESOURCES, 'resources'),\n listTool(LIST_MCP_RESOURCE_TEMPLATES, 'resourceTemplates'),\n defineTool({\n name: READ_MCP_RESOURCE,\n description: DESCRIPTIONS[READ_MCP_RESOURCE] as string,\n parameters: READ_PARAMETERS as never,\n replay: 'safe',\n async execute(args, api, context) {\n const read = await reading(\n await servers(api, context),\n args,\n signalOf(context),\n apiSaver(api, '', context)\n );\n return { content: read.content };\n },\n }) as ToolRegistration,\n ];\n}\n\nexport function resourceScriptTools(\n servers: () => readonly ResourceServer[],\n signal: AbortSignal | undefined,\n save: Saver\n): CodemodeTool[] {\n const combine = (own: AbortSignal) => (signal ? AbortSignal.any([own, signal]) : own);\n return [\n {\n name: LIST_MCP_RESOURCES,\n description: DESCRIPTIONS[LIST_MCP_RESOURCES] as string,\n inputSchema: LIST_PARAMETERS,\n execute: (args, { signal: own }) => listing(servers(), args, combine(own), 'resources'),\n },\n {\n name: LIST_MCP_RESOURCE_TEMPLATES,\n description: DESCRIPTIONS[LIST_MCP_RESOURCE_TEMPLATES] as string,\n inputSchema: LIST_PARAMETERS,\n execute: (args, { signal: own }) =>\n listing(servers(), args, combine(own), 'resourceTemplates'),\n },\n {\n name: READ_MCP_RESOURCE,\n description: DESCRIPTIONS[READ_MCP_RESOURCE] as string,\n inputSchema: READ_PARAMETERS,\n execute: async (args, { signal: own }) =>\n (await reading(servers(), args, combine(own), save)).payload,\n },\n ];\n}\n\nexport interface Namespace {\n name: string;\n description?: string;\n instructions?: string;\n}\n\nfunction isNamespaceName(namespace: string, query: string): boolean {\n const id = toCodemodeIdentifier(namespace);\n const queryId = toCodemodeIdentifier(query);\n const suffix = (name: string) => name.slice(name.lastIndexOf('__') + 2);\n return (\n namespace === query || id === queryId || suffix(namespace) === query || suffix(id) === queryId\n );\n}\n\nfunction words(text: string): string[] {\n return text\n .toLowerCase()\n .split(/[^a-z0-9]+/)\n .filter((word) => word.length > 1);\n}\n\nexport function rank(\n query: string,\n documents: readonly { name: string; text: string }[],\n limit: number\n): string[] {\n const terms = words(query);\n if (!terms.length) return [];\n const tokenized = documents.map((doc) => ({ name: doc.name, words: words(doc.text) }));\n const frequency = new Map<string, number>();\n for (const doc of tokenized)\n for (const term of new Set(doc.words)) frequency.set(term, (frequency.get(term) ?? 0) + 1);\n const total = tokenized.length;\n const scored = tokenized.map((doc) => {\n let score = 0;\n for (const term of terms) {\n const count = doc.words.filter((word) => word === term || word.startsWith(term)).length;\n if (!count) continue;\n const df = frequency.get(term) ?? 0;\n const idf = Math.log(1 + (total - df + 0.5) / (df + 0.5));\n score += idf * ((count * 2.2) / (count + 1.2 * (0.25 + (0.75 * doc.words.length) / 20)));\n }\n return { name: doc.name, score };\n });\n return scored\n .filter((doc) => doc.score > 0)\n .sort((a, b) => b.score - a.score || a.name.localeCompare(b.name))\n .slice(0, limit)\n .map((doc) => doc.name);\n}\n\nexport const DEFAULT_SEARCH_LIMIT = 8;\n\nexport function discoveryGlobals(\n tools: readonly CodemodeTool[],\n namespaceOf: (tool: string) => Namespace | undefined\n): CodemodeTool[] {\n const samples = new Map(tools.map((tool) => [tool.name, renderToolSample(tool)]));\n const entry = (name: string) => ({\n name: toCodemodeIdentifier(name),\n description: samples.get(name) as string,\n });\n return [\n {\n name: 'searchTools',\n spread: true,\n execute: (args) => {\n const [query, options] = args as [\n unknown,\n { limit?: unknown; namespace?: unknown } | undefined,\n ];\n if (typeof query !== 'string') throw new Error('searchTools() expects a query string');\n const limit = options?.limit ?? DEFAULT_SEARCH_LIMIT;\n if (typeof limit !== 'number' || !Number.isInteger(limit) || limit <= 0)\n throw new Error('searchTools() limit must be a positive integer');\n const namespace = options?.namespace;\n if (namespace !== undefined && namespace !== null && typeof namespace !== 'string')\n throw new Error('searchTools() namespace must be a string');\n const documents = tools.flatMap((tool) => {\n const space = namespaceOf(tool.name);\n if (namespace && (!space || !isNamespaceName(space.name, namespace))) return [];\n return [\n {\n name: tool.name,\n text: [\n tool.name.replace(/_/g, ' '),\n tool.description as string,\n space?.description ?? '',\n ].join(' '),\n },\n ];\n });\n return rank(query, documents, limit).map(entry);\n },\n },\n {\n name: 'describeTool',\n spread: true,\n execute: (args) => {\n const [name] = args as unknown[];\n if (typeof name !== 'string') throw new Error('describeTool() expects a tool name');\n const tool = tools.find(\n (candidate) => candidate.name === name || toCodemodeIdentifier(candidate.name) === name\n );\n return tool ? samples.get(tool.name) : undefined;\n },\n },\n {\n name: 'describeNamespace',\n spread: true,\n execute: (args) => {\n const [name] = args as unknown[];\n if (typeof name !== 'string')\n throw new Error('describeNamespace() expects a namespace name');\n let found: Namespace | undefined;\n const names: string[] = [];\n for (const tool of tools) {\n const space = namespaceOf(tool.name);\n if (!space || !isNamespaceName(space.name, name)) continue;\n found ??= space;\n names.push(toCodemodeIdentifier(tool.name));\n }\n if (!found) return undefined;\n return {\n name: found.name,\n ...(found.description ? { description: found.description } : {}),\n ...(found.instructions ? { instructions: found.instructions } : {}),\n tools: names,\n };\n },\n },\n ];\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["import type { Context, JsonValue } from '@earendil-works/chord';\nimport {\n type CodemodeJsonSchema,\n type CodemodeTool,\n renderToolSample,\n toCodemodeIdentifier,\n} from '@earendil-works/pi-codemode';\nimport {\n defineTool,\n type ToolExecutionApi,\n type ToolRegistration,\n} from '@earendil-works/pi-durable';\nimport type { McpRequestOptions, Tool as McpTool } from '@earendil-works/pi-mcp';\nimport { scrubbedOutput } from '../secrets/scrub.ts';\nimport type { McpExposure } from './config.ts';\nimport { errorMessage, type McpServerConnection } from './connection.ts';\nimport {\n type Content,\n convertResult,\n limitContent,\n modelContent,\n READ_MCP_RESOURCE,\n type Saver,\n scriptResult,\n spiller,\n} from './content.ts';\n\nexport const LIST_MCP_RESOURCES = 'list_mcp_resources';\nexport const LIST_MCP_RESOURCE_TEMPLATES = 'list_mcp_resource_templates';\nexport { READ_MCP_RESOURCE };\n\nexport interface McpToolEntry {\n server: string;\n name: string;\n exposure: McpExposure;\n tool: McpTool;\n connection: McpServerConnection;\n}\n\nexport type McpDetails = { server: string; tool: string; fullOutputPath?: string };\n\nfunction parametersOf(schema: Record<string, unknown>): Record<string, unknown> {\n const { $schema: _schema, ...rest } = schema;\n return {\n ...rest,\n type: rest.type ?? 'object',\n ...(rest.properties === undefined ? { properties: {} } : {}),\n };\n}\n\nexport function resultSchema(structured: Record<string, unknown> | undefined): CodemodeJsonSchema {\n return {\n type: 'object',\n properties: {\n content: { type: 'array', items: { type: 'object' } },\n ...(structured ? { structuredContent: structured } : {}),\n isError: { type: 'boolean' },\n },\n required: ['content'],\n };\n}\n\nfunction describe(entry: McpToolEntry): string {\n const title = entry.tool.title ?? entry.tool.annotations?.title;\n return (\n entry.tool.description?.trim() ||\n title ||\n `MCP tool ${entry.tool.name} from server ${entry.server}`\n );\n}\n\nfunction signalOf(context: Context): AbortSignal | undefined {\n return context.abortSignal as AbortSignal | undefined;\n}\n\nexport function apiSaver(api: ToolExecutionApi, prefix: string, context: Context): Saver {\n let counter = 0;\n return spiller(\n async (path, data, using) => (await api.env?.writeFile(path, data, using))?.ok === true,\n () => `${api.callId}-${prefix}${++counter}`,\n context\n );\n}\n\nfunction progressText(progress: { progress: number; total?: number; message?: string }): string {\n const total = progress.total === undefined ? '' : `/${progress.total}`;\n return progress.message ?? `Progress ${progress.progress}${total}`;\n}\n\nfunction failure(error: unknown): never {\n throw new Error(error instanceof Error ? error.message : String(error));\n}\n\nexport function directTool(entry: McpToolEntry, readable: () => boolean): ToolRegistration {\n return defineTool({\n name: entry.name,\n description: describe(entry),\n parameters: parametersOf(entry.tool.inputSchema) as never,\n replay: 'unsafe',\n async execute(args, api, context) {\n const save = apiSaver(api, '', context);\n const options: McpRequestOptions = {\n timeoutMs: entry.connection.timeoutMs,\n onProgress: (progress) => void scrubbedOutput(api, `${progressText(progress)}\\n`),\n };\n const signal = signalOf(context);\n if (signal) options.signal = signal;\n const result = await entry.connection\n .callTool(entry.tool.name, args as Record<string, unknown>, options)\n .catch(failure);\n const converted = await convertResult(\n entry.server,\n entry.tool.name,\n result,\n save,\n readable()\n );\n const details: McpDetails = {\n server: entry.server,\n tool: entry.tool.name,\n ...(converted.fullOutputPath ? { fullOutputPath: converted.fullOutputPath } : {}),\n };\n return {\n content: converted.content,\n details: details as JsonValue,\n ...(converted.isError ? { isError: true } : {}),\n };\n },\n }) as ToolRegistration;\n}\n\nexport function scriptTool(entry: McpToolEntry, signal: AbortSignal | undefined): CodemodeTool {\n const inputSchema = parametersOf(entry.tool.inputSchema);\n const outputSchema = resultSchema(entry.tool.outputSchema as Record<string, unknown> | undefined);\n return {\n name: entry.name,\n description: describe(entry),\n inputSchema,\n outputSchema,\n async execute(args, { signal: own }) {\n const combined = signal ? AbortSignal.any([own, signal]) : own;\n const result = await entry.connection\n .callTool(entry.tool.name, (args ?? {}) as Record<string, unknown>, {\n signal: combined,\n timeoutMs: entry.connection.timeoutMs,\n })\n .catch(failure);\n return scriptResult(result);\n },\n };\n}\n\nexport interface ResourceServer {\n name: string;\n connection: McpServerConnection;\n}\n\nfunction stringArgument(params: unknown, key: string): string | undefined {\n const value = (params as Record<string, unknown> | undefined)?.[key];\n if (value === undefined || value === null) return undefined;\n if (typeof value !== 'string') throw new Error(`${key} must be a string`);\n return value.trim() || undefined;\n}\n\nfunction listed(server: string, item: object): Record<string, unknown> {\n const { _meta, icons: _icons, ...rest } = item as Record<string, unknown>;\n return { server, ...rest };\n}\n\nconst stringProperty = (description: string) => ({ type: 'string', description });\nconst LIST_PARAMETERS = {\n type: 'object',\n properties: {\n server: stringProperty('MCP server name. Omit to list every server with resources.'),\n cursor: stringProperty(\n 'Opaque cursor from a previous call with the same server; omit for the first page.'\n ),\n },\n additionalProperties: false,\n};\nconst READ_PARAMETERS = {\n type: 'object',\n properties: {\n server: stringProperty(\n \"MCP server name exactly as configured. Must match the 'server' field returned by list_mcp_resources.\"\n ),\n uri: stringProperty(\n 'Resource URI to read. Must be one of the URIs returned by list_mcp_resources.'\n ),\n },\n required: ['server', 'uri'],\n additionalProperties: false,\n};\n\nconst DESCRIPTIONS: Record<string, string> = {\n [LIST_MCP_RESOURCES]:\n 'Lists resources provided by MCP servers. Resources allow servers to share data that provides context to language models, such as files, database schemas, or application-specific information. Prefer resources over web search when possible.',\n [LIST_MCP_RESOURCE_TEMPLATES]:\n 'Lists resource templates provided by MCP servers. Parameterized resource templates allow servers to share data that takes parameters and provides context to language models, such as files, database schemas, or application-specific information. Prefer resource templates over web search when possible.',\n [READ_MCP_RESOURCE]:\n 'Read a specific resource from an MCP server given the server name and resource URI.',\n};\n\ntype Key = 'resources' | 'resourceTemplates';\n\nfunction find(servers: readonly ResourceServer[], name: string): ResourceServer {\n const server = servers.find((candidate) => candidate.name === name);\n if (server) return server;\n const available = servers.map((candidate) => candidate.name).join(', ');\n throw new Error(\n `MCP server \"${name}\" has no resources${available ? `. Servers with resources: ${available}` : ''}`\n );\n}\n\nasync function listing(\n servers: readonly ResourceServer[],\n params: unknown,\n signal: AbortSignal | undefined,\n key: Key\n): Promise<Record<string, unknown>> {\n const serverName = stringArgument(params, 'server');\n const cursor = stringArgument(params, 'cursor');\n const visible = (item: object) => {\n const { uri, uriTemplate, mimeType } = item as Record<string, string | undefined>;\n const target = uri ?? uriTemplate ?? '';\n return !(target.startsWith('ui://') || /;\\s*profile\\s*=\\s*\"?mcp-app\"?/i.test(mimeType ?? ''));\n };\n const options = (server: ResourceServer): McpRequestOptions => ({\n timeoutMs: server.connection.timeoutMs,\n ...(signal ? { signal } : {}),\n });\n if (serverName) {\n const server = find(servers, serverName);\n const page =\n key === 'resources'\n ? await server.connection.resourcesPage(cursor, options(server)).then((result) => ({\n items: result.resources as object[],\n nextCursor: result.nextCursor,\n }))\n : await server.connection.resourceTemplatesPage(cursor, options(server)).then((result) => ({\n items: result.resourceTemplates as object[],\n nextCursor: result.nextCursor,\n }));\n return {\n server: server.name,\n [key]: page.items.filter(visible).map((item) => listed(server.name, item)),\n ...(page.nextCursor === undefined ? {} : { nextCursor: page.nextCursor }),\n };\n }\n if (cursor) throw new Error('cursor can only be used when a server is specified');\n const sorted = [...servers].sort((a, b) => a.name.localeCompare(b.name));\n const results = await Promise.allSettled(\n sorted.map((server) =>\n key === 'resources'\n ? server.connection.allResources(options(server))\n : server.connection.allResourceTemplates(options(server))\n )\n );\n const items: Record<string, unknown>[] = [];\n const errors: { server: string; error: string }[] = [];\n results.forEach((result, index) => {\n const server = (sorted[index] as ResourceServer).name;\n if (result.status === 'fulfilled')\n items.push(...(result.value as object[]).filter(visible).map((item) => listed(server, item)));\n else\n errors.push({\n server,\n error: errorMessage(result.reason),\n });\n });\n return { [key]: items, ...(errors.length ? { errors } : {}) };\n}\n\nasync function reading(\n servers: readonly ResourceServer[],\n params: unknown,\n signal: AbortSignal | undefined,\n save: Saver\n): Promise<{ content: Content[]; payload: Record<string, unknown>; fullOutputPath?: string }> {\n const serverName = stringArgument(params, 'server');\n const uri = stringArgument(params, 'uri');\n if (!serverName) throw new Error('server must be provided');\n if (!uri) throw new Error('uri must be provided');\n const server = find(servers, serverName);\n const result = await server.connection.readResource(uri, {\n timeoutMs: server.connection.timeoutMs,\n ...(signal ? { signal } : {}),\n });\n const blocks = result.contents.flatMap((contents) => [\n ...(result.contents.length > 1 ? [{ type: 'text' as const, text: `${contents.uri}:` }] : []),\n { type: 'resource' as const, resource: contents },\n ]);\n const converted = await modelContent(server.name, blocks, save);\n const limited = await limitContent(\n converted.length ? converted : [{ type: 'text', text: `Resource ${uri} is empty.` }],\n save\n );\n const contents = result.contents.map((item) => {\n const { _meta: _ignored, ...rest } = item as typeof item & { _meta?: unknown };\n return rest;\n });\n return { ...limited, payload: { server: server.name, uri, contents } };\n}\n\nexport type ServersFor = (\n api: ToolExecutionApi,\n context: Context\n) => Promise<readonly ResourceServer[]>;\n\nexport function resourceTools(servers: ServersFor): ToolRegistration[] {\n const listTool = (name: string, key: Key) =>\n defineTool({\n name,\n description: DESCRIPTIONS[name] as string,\n parameters: LIST_PARAMETERS as never,\n replay: 'safe',\n async execute(args, api, context) {\n const payload = await listing(await servers(api, context), args, signalOf(context), key);\n const limited = await limitContent(\n [{ type: 'text', text: JSON.stringify(payload) }],\n apiSaver(api, '', context)\n );\n return { content: limited.content };\n },\n }) as ToolRegistration;\n return [\n listTool(LIST_MCP_RESOURCES, 'resources'),\n listTool(LIST_MCP_RESOURCE_TEMPLATES, 'resourceTemplates'),\n defineTool({\n name: READ_MCP_RESOURCE,\n description: DESCRIPTIONS[READ_MCP_RESOURCE] as string,\n parameters: READ_PARAMETERS as never,\n replay: 'safe',\n async execute(args, api, context) {\n const read = await reading(\n await servers(api, context),\n args,\n signalOf(context),\n apiSaver(api, '', context)\n );\n return { content: read.content };\n },\n }) as ToolRegistration,\n ];\n}\n\nexport function resourceScriptTools(\n servers: () => readonly ResourceServer[],\n signal: AbortSignal | undefined,\n save: Saver\n): CodemodeTool[] {\n const combine = (own: AbortSignal) => (signal ? AbortSignal.any([own, signal]) : own);\n return [\n {\n name: LIST_MCP_RESOURCES,\n description: DESCRIPTIONS[LIST_MCP_RESOURCES] as string,\n inputSchema: LIST_PARAMETERS,\n execute: (args, { signal: own }) => listing(servers(), args, combine(own), 'resources'),\n },\n {\n name: LIST_MCP_RESOURCE_TEMPLATES,\n description: DESCRIPTIONS[LIST_MCP_RESOURCE_TEMPLATES] as string,\n inputSchema: LIST_PARAMETERS,\n execute: (args, { signal: own }) =>\n listing(servers(), args, combine(own), 'resourceTemplates'),\n },\n {\n name: READ_MCP_RESOURCE,\n description: DESCRIPTIONS[READ_MCP_RESOURCE] as string,\n inputSchema: READ_PARAMETERS,\n execute: async (args, { signal: own }) =>\n (await reading(servers(), args, combine(own), save)).payload,\n },\n ];\n}\n\nexport interface Namespace {\n name: string;\n description?: string;\n instructions?: string;\n}\n\nfunction isNamespaceName(namespace: string, query: string): boolean {\n const id = toCodemodeIdentifier(namespace);\n const queryId = toCodemodeIdentifier(query);\n const suffix = (name: string) => name.slice(name.lastIndexOf('__') + 2);\n return (\n namespace === query || id === queryId || suffix(namespace) === query || suffix(id) === queryId\n );\n}\n\nfunction words(text: string): string[] {\n return text\n .toLowerCase()\n .split(/[^a-z0-9]+/)\n .filter((word) => word.length > 1);\n}\n\nexport function rank(\n query: string,\n documents: readonly { name: string; text: string }[],\n limit: number\n): string[] {\n const terms = words(query);\n if (!terms.length) return [];\n const tokenized = documents.map((doc) => ({ name: doc.name, words: words(doc.text) }));\n const frequency = new Map<string, number>();\n for (const doc of tokenized)\n for (const term of new Set(doc.words)) frequency.set(term, (frequency.get(term) ?? 0) + 1);\n const total = tokenized.length;\n const scored = tokenized.map((doc) => {\n let score = 0;\n for (const term of terms) {\n const count = doc.words.filter((word) => word === term || word.startsWith(term)).length;\n if (!count) continue;\n const df = frequency.get(term) ?? 0;\n const idf = Math.log(1 + (total - df + 0.5) / (df + 0.5));\n score += idf * ((count * 2.2) / (count + 1.2 * (0.25 + (0.75 * doc.words.length) / 20)));\n }\n return { name: doc.name, score };\n });\n return scored\n .filter((doc) => doc.score > 0)\n .sort((a, b) => b.score - a.score || a.name.localeCompare(b.name))\n .slice(0, limit)\n .map((doc) => doc.name);\n}\n\nexport const DEFAULT_SEARCH_LIMIT = 8;\n\nexport function discoveryGlobals(\n tools: readonly CodemodeTool[],\n namespaceOf: (tool: string) => Namespace | undefined\n): CodemodeTool[] {\n const samples = new Map(tools.map((tool) => [tool.name, renderToolSample(tool)]));\n const entry = (name: string) => ({\n name: toCodemodeIdentifier(name),\n description: samples.get(name) as string,\n });\n return [\n {\n name: 'searchTools',\n spread: true,\n execute: (args) => {\n const [query, options] = args as [\n unknown,\n { limit?: unknown; namespace?: unknown } | undefined,\n ];\n if (typeof query !== 'string') throw new Error('searchTools() expects a query string');\n const limit = options?.limit ?? DEFAULT_SEARCH_LIMIT;\n if (typeof limit !== 'number' || !Number.isInteger(limit) || limit <= 0)\n throw new Error('searchTools() limit must be a positive integer');\n const namespace = options?.namespace;\n if (namespace !== undefined && namespace !== null && typeof namespace !== 'string')\n throw new Error('searchTools() namespace must be a string');\n const documents = tools.flatMap((tool) => {\n const space = namespaceOf(tool.name);\n if (namespace && (!space || !isNamespaceName(space.name, namespace))) return [];\n return [\n {\n name: tool.name,\n text: [\n tool.name.replace(/_/g, ' '),\n tool.description as string,\n space?.description ?? '',\n ].join(' '),\n },\n ];\n });\n return rank(query, documents, limit).map(entry);\n },\n },\n {\n name: 'describeTool',\n spread: true,\n execute: (args) => {\n const [name] = args as unknown[];\n if (typeof name !== 'string') throw new Error('describeTool() expects a tool name');\n const tool = tools.find(\n (candidate) => candidate.name === name || toCodemodeIdentifier(candidate.name) === name\n );\n return tool ? samples.get(tool.name) : undefined;\n },\n },\n {\n name: 'describeNamespace',\n spread: true,\n execute: (args) => {\n const [name] = args as unknown[];\n if (typeof name !== 'string')\n throw new Error('describeNamespace() expects a namespace name');\n let found: Namespace | undefined;\n const names: string[] = [];\n for (const tool of tools) {\n const space = namespaceOf(tool.name);\n if (!space || !isNamespaceName(space.name, name)) continue;\n found ??= space;\n names.push(toCodemodeIdentifier(tool.name));\n }\n if (!found) return undefined;\n return {\n name: found.name,\n ...(found.description ? { description: found.description } : {}),\n ...(found.instructions ? { instructions: found.instructions } : {}),\n tools: names,\n };\n },\n },\n ];\n}\n"],
|
|
5
|
+
"mappings": "AACA;AAAA,EAGE;AAAA,EACA;AAAA,OACK;AACP;AAAA,EACE;AAAA,OAGK;AAEP,SAAS,sBAAsB;AAE/B,SAAS,oBAA8C;AACvD;AAAA,EAEE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAEA;AAAA,EACA;AAAA,OACK;AAEA,MAAM,qBAAqB;AAC3B,MAAM,8BAA8B;AAa3C,SAAS,aAAa,QAA0D;AAC9E,QAAM,EAAE,SAAS,SAAS,GAAG,KAAK,IAAI;AACtC,SAAO;AAAA,IACL,GAAG;AAAA,IACH,MAAM,KAAK,QAAQ;AAAA,IACnB,GAAI,KAAK,eAAe,SAAY,EAAE,YAAY,CAAC,EAAE,IAAI,CAAC;AAAA,EAC5D;AACF;AAEO,SAAS,aAAa,YAAqE;AAChG,SAAO;AAAA,IACL,MAAM;AAAA,IACN,YAAY;AAAA,MACV,SAAS,EAAE,MAAM,SAAS,OAAO,EAAE,MAAM,SAAS,EAAE;AAAA,MACpD,GAAI,aAAa,EAAE,mBAAmB,WAAW,IAAI,CAAC;AAAA,MACtD,SAAS,EAAE,MAAM,UAAU;AAAA,IAC7B;AAAA,IACA,UAAU,CAAC,SAAS;AAAA,EACtB;AACF;AAEA,SAAS,SAAS,OAA6B;AAC7C,QAAM,QAAQ,MAAM,KAAK,SAAS,MAAM,KAAK,aAAa;AAC1D,SACE,MAAM,KAAK,aAAa,KAAK,KAC7B,SACA,YAAY,MAAM,KAAK,IAAI,gBAAgB,MAAM,MAAM;AAE3D;AAEA,SAAS,SAAS,SAA2C;AAC3D,SAAO,QAAQ;AACjB;AAEO,SAAS,SAAS,KAAuB,QAAgB,SAAyB;AACvF,MAAI,UAAU;AACd,SAAO;AAAA,IACL,OAAO,MAAM,MAAM,WAAW,MAAM,IAAI,KAAK,UAAU,MAAM,MAAM,KAAK,IAAI,OAAO;AAAA,IACnF,MAAM,GAAG,IAAI,MAAM,IAAI,MAAM,GAAG,EAAE,OAAO;AAAA,IACzC;AAAA,EACF;AACF;AAEA,SAAS,aAAa,UAA0E;AAC9F,QAAM,QAAQ,SAAS,UAAU,SAAY,KAAK,IAAI,SAAS,KAAK;AACpE,SAAO,SAAS,WAAW,YAAY,SAAS,QAAQ,GAAG,KAAK;AAClE;AAEA,SAAS,QAAQ,OAAuB;AACtC,QAAM,IAAI,MAAM,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AACxE;AAEO,SAAS,WAAW,OAAqB,UAA2C;AACzF,SAAO,WAAW;AAAA,IAChB,MAAM,MAAM;AAAA,IACZ,aAAa,SAAS,KAAK;AAAA,IAC3B,YAAY,aAAa,MAAM,KAAK,WAAW;AAAA,IAC/C,QAAQ;AAAA,IACR,MAAM,QAAQ,MAAM,KAAK,SAAS;AAChC,YAAM,OAAO,SAAS,KAAK,IAAI,OAAO;AACtC,YAAM,UAA6B;AAAA,QACjC,WAAW,MAAM,WAAW;AAAA,QAC5B,YAAY,CAAC,aAAa,KAAK,eAAe,KAAK,GAAG,aAAa,QAAQ,CAAC;AAAA,CAAI;AAAA,MAClF;AACA,YAAM,SAAS,SAAS,OAAO;AAC/B,UAAI,OAAQ,SAAQ,SAAS;AAC7B,YAAM,SAAS,MAAM,MAAM,WACxB,SAAS,MAAM,KAAK,MAAM,MAAiC,OAAO,EAClE,MAAM,OAAO;AAChB,YAAM,YAAY,MAAM;AAAA,QACtB,MAAM;AAAA,QACN,MAAM,KAAK;AAAA,QACX;AAAA,QACA;AAAA,QACA,SAAS;AAAA,MACX;AACA,YAAM,UAAsB;AAAA,QAC1B,QAAQ,MAAM;AAAA,QACd,MAAM,MAAM,KAAK;AAAA,QACjB,GAAI,UAAU,iBAAiB,EAAE,gBAAgB,UAAU,eAAe,IAAI,CAAC;AAAA,MACjF;AACA,aAAO;AAAA,QACL,SAAS,UAAU;AAAA,QACnB;AAAA,QACA,GAAI,UAAU,UAAU,EAAE,SAAS,KAAK,IAAI,CAAC;AAAA,MAC/C;AAAA,IACF;AAAA,EACF,CAAC;AACH;AAEO,SAAS,WAAW,OAAqB,QAA+C;AAC7F,QAAM,cAAc,aAAa,MAAM,KAAK,WAAW;AACvD,QAAM,eAAe,aAAa,MAAM,KAAK,YAAmD;AAChG,SAAO;AAAA,IACL,MAAM,MAAM;AAAA,IACZ,aAAa,SAAS,KAAK;AAAA,IAC3B;AAAA,IACA;AAAA,IACA,MAAM,QAAQ,MAAM,EAAE,QAAQ,IAAI,GAAG;AACnC,YAAM,WAAW,SAAS,YAAY,IAAI,CAAC,KAAK,MAAM,CAAC,IAAI;AAC3D,YAAM,SAAS,MAAM,MAAM,WACxB,SAAS,MAAM,KAAK,MAAO,QAAQ,CAAC,GAA+B;AAAA,QAClE,QAAQ;AAAA,QACR,WAAW,MAAM,WAAW;AAAA,MAC9B,CAAC,EACA,MAAM,OAAO;AAChB,aAAO,aAAa,MAAM;AAAA,IAC5B;AAAA,EACF;AACF;AAOA,SAAS,eAAe,QAAiB,KAAiC;AACxE,QAAM,QAAS,SAAiD,GAAG;AACnE,MAAI,UAAU,UAAa,UAAU,KAAM,QAAO;AAClD,MAAI,OAAO,UAAU,SAAU,OAAM,IAAI,MAAM,GAAG,GAAG,mBAAmB;AACxE,SAAO,MAAM,KAAK,KAAK;AACzB;AAEA,SAAS,OAAO,QAAgB,MAAuC;AACrE,QAAM,EAAE,OAAO,OAAO,QAAQ,GAAG,KAAK,IAAI;AAC1C,SAAO,EAAE,QAAQ,GAAG,KAAK;AAC3B;AAEA,MAAM,iBAAiB,CAAC,iBAAyB,EAAE,MAAM,UAAU,YAAY;AAC/E,MAAM,kBAAkB;AAAA,EACtB,MAAM;AAAA,EACN,YAAY;AAAA,IACV,QAAQ,eAAe,4DAA4D;AAAA,IACnF,QAAQ;AAAA,MACN;AAAA,IACF;AAAA,EACF;AAAA,EACA,sBAAsB;AACxB;AACA,MAAM,kBAAkB;AAAA,EACtB,MAAM;AAAA,EACN,YAAY;AAAA,IACV,QAAQ;AAAA,MACN;AAAA,IACF;AAAA,IACA,KAAK;AAAA,MACH;AAAA,IACF;AAAA,EACF;AAAA,EACA,UAAU,CAAC,UAAU,KAAK;AAAA,EAC1B,sBAAsB;AACxB;AAEA,MAAM,eAAuC;AAAA,EAC3C,CAAC,kBAAkB,GACjB;AAAA,EACF,CAAC,2BAA2B,GAC1B;AAAA,EACF,CAAC,iBAAiB,GAChB;AACJ;AAIA,SAAS,KAAK,SAAoC,MAA8B;AAC9E,QAAM,SAAS,QAAQ,KAAK,CAAC,cAAc,UAAU,SAAS,IAAI;AAClE,MAAI,OAAQ,QAAO;AACnB,QAAM,YAAY,QAAQ,IAAI,CAAC,cAAc,UAAU,IAAI,EAAE,KAAK,IAAI;AACtE,QAAM,IAAI;AAAA,IACR,eAAe,IAAI,qBAAqB,YAAY,6BAA6B,SAAS,KAAK,EAAE;AAAA,EACnG;AACF;AAEA,eAAe,QACb,SACA,QACA,QACA,KACkC;AAClC,QAAM,aAAa,eAAe,QAAQ,QAAQ;AAClD,QAAM,SAAS,eAAe,QAAQ,QAAQ;AAC9C,QAAM,UAAU,CAAC,SAAiB;AAChC,UAAM,EAAE,KAAK,aAAa,SAAS,IAAI;AACvC,UAAM,SAAS,OAAO,eAAe;AACrC,WAAO,EAAE,OAAO,WAAW,OAAO,KAAK,iCAAiC,KAAK,YAAY,EAAE;AAAA,EAC7F;AACA,QAAM,UAAU,CAAC,YAA+C;AAAA,IAC9D,WAAW,OAAO,WAAW;AAAA,IAC7B,GAAI,SAAS,EAAE,OAAO,IAAI,CAAC;AAAA,EAC7B;AACA,MAAI,YAAY;AACd,UAAM,SAAS,KAAK,SAAS,UAAU;AACvC,UAAM,OACJ,QAAQ,cACJ,MAAM,OAAO,WAAW,cAAc,QAAQ,QAAQ,MAAM,CAAC,EAAE,KAAK,CAAC,YAAY;AAAA,MAC/E,OAAO,OAAO;AAAA,MACd,YAAY,OAAO;AAAA,IACrB,EAAE,IACF,MAAM,OAAO,WAAW,sBAAsB,QAAQ,QAAQ,MAAM,CAAC,EAAE,KAAK,CAAC,YAAY;AAAA,MACvF,OAAO,OAAO;AAAA,MACd,YAAY,OAAO;AAAA,IACrB,EAAE;AACR,WAAO;AAAA,MACL,QAAQ,OAAO;AAAA,MACf,CAAC,GAAG,GAAG,KAAK,MAAM,OAAO,OAAO,EAAE,IAAI,CAAC,SAAS,OAAO,OAAO,MAAM,IAAI,CAAC;AAAA,MACzE,GAAI,KAAK,eAAe,SAAY,CAAC,IAAI,EAAE,YAAY,KAAK,WAAW;AAAA,IACzE;AAAA,EACF;AACA,MAAI,OAAQ,OAAM,IAAI,MAAM,oDAAoD;AAChF,QAAM,SAAS,CAAC,GAAG,OAAO,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,KAAK,cAAc,EAAE,IAAI,CAAC;AACvE,QAAM,UAAU,MAAM,QAAQ;AAAA,IAC5B,OAAO;AAAA,MAAI,CAAC,WACV,QAAQ,cACJ,OAAO,WAAW,aAAa,QAAQ,MAAM,CAAC,IAC9C,OAAO,WAAW,qBAAqB,QAAQ,MAAM,CAAC;AAAA,IAC5D;AAAA,EACF;AACA,QAAM,QAAmC,CAAC;AAC1C,QAAM,SAA8C,CAAC;AACrD,UAAQ,QAAQ,CAAC,QAAQ,UAAU;AACjC,UAAM,SAAU,OAAO,KAAK,EAAqB;AACjD,QAAI,OAAO,WAAW;AACpB,YAAM,KAAK,GAAI,OAAO,MAAmB,OAAO,OAAO,EAAE,IAAI,CAAC,SAAS,OAAO,QAAQ,IAAI,CAAC,CAAC;AAAA;AAE5F,aAAO,KAAK;AAAA,QACV;AAAA,QACA,OAAO,aAAa,OAAO,MAAM;AAAA,MACnC,CAAC;AAAA,EACL,CAAC;AACD,SAAO,EAAE,CAAC,GAAG,GAAG,OAAO,GAAI,OAAO,SAAS,EAAE,OAAO,IAAI,CAAC,EAAG;AAC9D;AAEA,eAAe,QACb,SACA,QACA,QACA,MAC4F;AAC5F,QAAM,aAAa,eAAe,QAAQ,QAAQ;AAClD,QAAM,MAAM,eAAe,QAAQ,KAAK;AACxC,MAAI,CAAC,WAAY,OAAM,IAAI,MAAM,yBAAyB;AAC1D,MAAI,CAAC,IAAK,OAAM,IAAI,MAAM,sBAAsB;AAChD,QAAM,SAAS,KAAK,SAAS,UAAU;AACvC,QAAM,SAAS,MAAM,OAAO,WAAW,aAAa,KAAK;AAAA,IACvD,WAAW,OAAO,WAAW;AAAA,IAC7B,GAAI,SAAS,EAAE,OAAO,IAAI,CAAC;AAAA,EAC7B,CAAC;AACD,QAAM,SAAS,OAAO,SAAS,QAAQ,CAACA,cAAa;AAAA,IACnD,GAAI,OAAO,SAAS,SAAS,IAAI,CAAC,EAAE,MAAM,QAAiB,MAAM,GAAGA,UAAS,GAAG,IAAI,CAAC,IAAI,CAAC;AAAA,IAC1F,EAAE,MAAM,YAAqB,UAAUA,UAAS;AAAA,EAClD,CAAC;AACD,QAAM,YAAY,MAAM,aAAa,OAAO,MAAM,QAAQ,IAAI;AAC9D,QAAM,UAAU,MAAM;AAAA,IACpB,UAAU,SAAS,YAAY,CAAC,EAAE,MAAM,QAAQ,MAAM,YAAY,GAAG,aAAa,CAAC;AAAA,IACnF;AAAA,EACF;AACA,QAAM,WAAW,OAAO,SAAS,IAAI,CAAC,SAAS;AAC7C,UAAM,EAAE,OAAO,UAAU,GAAG,KAAK,IAAI;AACrC,WAAO;AAAA,EACT,CAAC;AACD,SAAO,EAAE,GAAG,SAAS,SAAS,EAAE,QAAQ,OAAO,MAAM,KAAK,SAAS,EAAE;AACvE;AAOO,SAAS,cAAc,SAAyC;AACrE,QAAM,WAAW,CAAC,MAAc,QAC9B,WAAW;AAAA,IACT;AAAA,IACA,aAAa,aAAa,IAAI;AAAA,IAC9B,YAAY;AAAA,IACZ,QAAQ;AAAA,IACR,MAAM,QAAQ,MAAM,KAAK,SAAS;AAChC,YAAM,UAAU,MAAM,QAAQ,MAAM,QAAQ,KAAK,OAAO,GAAG,MAAM,SAAS,OAAO,GAAG,GAAG;AACvF,YAAM,UAAU,MAAM;AAAA,QACpB,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,OAAO,EAAE,CAAC;AAAA,QAChD,SAAS,KAAK,IAAI,OAAO;AAAA,MAC3B;AACA,aAAO,EAAE,SAAS,QAAQ,QAAQ;AAAA,IACpC;AAAA,EACF,CAAC;AACH,SAAO;AAAA,IACL,SAAS,oBAAoB,WAAW;AAAA,IACxC,SAAS,6BAA6B,mBAAmB;AAAA,IACzD,WAAW;AAAA,MACT,MAAM;AAAA,MACN,aAAa,aAAa,iBAAiB;AAAA,MAC3C,YAAY;AAAA,MACZ,QAAQ;AAAA,MACR,MAAM,QAAQ,MAAM,KAAK,SAAS;AAChC,cAAM,OAAO,MAAM;AAAA,UACjB,MAAM,QAAQ,KAAK,OAAO;AAAA,UAC1B;AAAA,UACA,SAAS,OAAO;AAAA,UAChB,SAAS,KAAK,IAAI,OAAO;AAAA,QAC3B;AACA,eAAO,EAAE,SAAS,KAAK,QAAQ;AAAA,MACjC;AAAA,IACF,CAAC;AAAA,EACH;AACF;AAEO,SAAS,oBACd,SACA,QACA,MACgB;AAChB,QAAM,UAAU,CAAC,QAAsB,SAAS,YAAY,IAAI,CAAC,KAAK,MAAM,CAAC,IAAI;AACjF,SAAO;AAAA,IACL;AAAA,MACE,MAAM;AAAA,MACN,aAAa,aAAa,kBAAkB;AAAA,MAC5C,aAAa;AAAA,MACb,SAAS,CAAC,MAAM,EAAE,QAAQ,IAAI,MAAM,QAAQ,QAAQ,GAAG,MAAM,QAAQ,GAAG,GAAG,WAAW;AAAA,IACxF;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,aAAa,aAAa,2BAA2B;AAAA,MACrD,aAAa;AAAA,MACb,SAAS,CAAC,MAAM,EAAE,QAAQ,IAAI,MAC5B,QAAQ,QAAQ,GAAG,MAAM,QAAQ,GAAG,GAAG,mBAAmB;AAAA,IAC9D;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,aAAa,aAAa,iBAAiB;AAAA,MAC3C,aAAa;AAAA,MACb,SAAS,OAAO,MAAM,EAAE,QAAQ,IAAI,OACjC,MAAM,QAAQ,QAAQ,GAAG,MAAM,QAAQ,GAAG,GAAG,IAAI,GAAG;AAAA,IACzD;AAAA,EACF;AACF;AAQA,SAAS,gBAAgB,WAAmB,OAAwB;AAClE,QAAM,KAAK,qBAAqB,SAAS;AACzC,QAAM,UAAU,qBAAqB,KAAK;AAC1C,QAAM,SAAS,CAAC,SAAiB,KAAK,MAAM,KAAK,YAAY,IAAI,IAAI,CAAC;AACtE,SACE,cAAc,SAAS,OAAO,WAAW,OAAO,SAAS,MAAM,SAAS,OAAO,EAAE,MAAM;AAE3F;AAEA,SAAS,MAAM,MAAwB;AACrC,SAAO,KACJ,YAAY,EACZ,MAAM,YAAY,EAClB,OAAO,CAAC,SAAS,KAAK,SAAS,CAAC;AACrC;AAEO,SAAS,KACd,OACA,WACA,OACU;AACV,QAAM,QAAQ,MAAM,KAAK;AACzB,MAAI,CAAC,MAAM,OAAQ,QAAO,CAAC;AAC3B,QAAM,YAAY,UAAU,IAAI,CAAC,SAAS,EAAE,MAAM,IAAI,MAAM,OAAO,MAAM,IAAI,IAAI,EAAE,EAAE;AACrF,QAAM,YAAY,oBAAI,IAAoB;AAC1C,aAAW,OAAO;AAChB,eAAW,QAAQ,IAAI,IAAI,IAAI,KAAK,EAAG,WAAU,IAAI,OAAO,UAAU,IAAI,IAAI,KAAK,KAAK,CAAC;AAC3F,QAAM,QAAQ,UAAU;AACxB,QAAM,SAAS,UAAU,IAAI,CAAC,QAAQ;AACpC,QAAI,QAAQ;AACZ,eAAW,QAAQ,OAAO;AACxB,YAAM,QAAQ,IAAI,MAAM,OAAO,CAAC,SAAS,SAAS,QAAQ,KAAK,WAAW,IAAI,CAAC,EAAE;AACjF,UAAI,CAAC,MAAO;AACZ,YAAM,KAAK,UAAU,IAAI,IAAI,KAAK;AAClC,YAAM,MAAM,KAAK,IAAI,KAAK,QAAQ,KAAK,QAAQ,KAAK,IAAI;AACxD,eAAS,OAAQ,QAAQ,OAAQ,QAAQ,OAAO,OAAQ,OAAO,IAAI,MAAM,SAAU;AAAA,IACrF;AACA,WAAO,EAAE,MAAM,IAAI,MAAM,MAAM;AAAA,EACjC,CAAC;AACD,SAAO,OACJ,OAAO,CAAC,QAAQ,IAAI,QAAQ,CAAC,EAC7B,KAAK,CAAC,GAAG,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK,cAAc,EAAE,IAAI,CAAC,EAChE,MAAM,GAAG,KAAK,EACd,IAAI,CAAC,QAAQ,IAAI,IAAI;AAC1B;AAEO,MAAM,uBAAuB;AAE7B,SAAS,iBACd,OACA,aACgB;AAChB,QAAM,UAAU,IAAI,IAAI,MAAM,IAAI,CAAC,SAAS,CAAC,KAAK,MAAM,iBAAiB,IAAI,CAAC,CAAC,CAAC;AAChF,QAAM,QAAQ,CAAC,UAAkB;AAAA,IAC/B,MAAM,qBAAqB,IAAI;AAAA,IAC/B,aAAa,QAAQ,IAAI,IAAI;AAAA,EAC/B;AACA,SAAO;AAAA,IACL;AAAA,MACE,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,SAAS,CAAC,SAAS;AACjB,cAAM,CAAC,OAAO,OAAO,IAAI;AAIzB,YAAI,OAAO,UAAU,SAAU,OAAM,IAAI,MAAM,sCAAsC;AACrF,cAAM,QAAQ,SAAS,SAAS;AAChC,YAAI,OAAO,UAAU,YAAY,CAAC,OAAO,UAAU,KAAK,KAAK,SAAS;AACpE,gBAAM,IAAI,MAAM,gDAAgD;AAClE,cAAM,YAAY,SAAS;AAC3B,YAAI,cAAc,UAAa,cAAc,QAAQ,OAAO,cAAc;AACxE,gBAAM,IAAI,MAAM,0CAA0C;AAC5D,cAAM,YAAY,MAAM,QAAQ,CAAC,SAAS;AACxC,gBAAM,QAAQ,YAAY,KAAK,IAAI;AACnC,cAAI,cAAc,CAAC,SAAS,CAAC,gBAAgB,MAAM,MAAM,SAAS,GAAI,QAAO,CAAC;AAC9E,iBAAO;AAAA,YACL;AAAA,cACE,MAAM,KAAK;AAAA,cACX,MAAM;AAAA,gBACJ,KAAK,KAAK,QAAQ,MAAM,GAAG;AAAA,gBAC3B,KAAK;AAAA,gBACL,OAAO,eAAe;AAAA,cACxB,EAAE,KAAK,GAAG;AAAA,YACZ;AAAA,UACF;AAAA,QACF,CAAC;AACD,eAAO,KAAK,OAAO,WAAW,KAAK,EAAE,IAAI,KAAK;AAAA,MAChD;AAAA,IACF;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,SAAS,CAAC,SAAS;AACjB,cAAM,CAAC,IAAI,IAAI;AACf,YAAI,OAAO,SAAS,SAAU,OAAM,IAAI,MAAM,oCAAoC;AAClF,cAAM,OAAO,MAAM;AAAA,UACjB,CAAC,cAAc,UAAU,SAAS,QAAQ,qBAAqB,UAAU,IAAI,MAAM;AAAA,QACrF;AACA,eAAO,OAAO,QAAQ,IAAI,KAAK,IAAI,IAAI;AAAA,MACzC;AAAA,IACF;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,SAAS,CAAC,SAAS;AACjB,cAAM,CAAC,IAAI,IAAI;AACf,YAAI,OAAO,SAAS;AAClB,gBAAM,IAAI,MAAM,8CAA8C;AAChE,YAAI;AACJ,cAAM,QAAkB,CAAC;AACzB,mBAAW,QAAQ,OAAO;AACxB,gBAAM,QAAQ,YAAY,KAAK,IAAI;AACnC,cAAI,CAAC,SAAS,CAAC,gBAAgB,MAAM,MAAM,IAAI,EAAG;AAClD,oBAAU;AACV,gBAAM,KAAK,qBAAqB,KAAK,IAAI,CAAC;AAAA,QAC5C;AACA,YAAI,CAAC,MAAO,QAAO;AACnB,eAAO;AAAA,UACL,MAAM,MAAM;AAAA,UACZ,GAAI,MAAM,cAAc,EAAE,aAAa,MAAM,YAAY,IAAI,CAAC;AAAA,UAC9D,GAAI,MAAM,eAAe,EAAE,cAAc,MAAM,aAAa,IAAI,CAAC;AAAA,UACjE,OAAO;AAAA,QACT;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;",
|
|
6
6
|
"names": ["contents"]
|
|
7
7
|
}
|
package/dist/models/index.js
CHANGED
|
@@ -8,6 +8,7 @@ const USAGE = `usage:
|
|
|
8
8
|
levels: ${LEVELS}
|
|
9
9
|
In an agent's bash, models switches that cone or scoop; in a terminal, the active cone.
|
|
10
10
|
`;
|
|
11
|
+
const LOCKED_NOTE = "the vault is locked: unlock it to use these accounts";
|
|
11
12
|
const ok = (out) => ({ code: 0, out });
|
|
12
13
|
const fail = (out, code = 1) => ({ code, out: `models: ${out}
|
|
13
14
|
` });
|
|
@@ -78,14 +79,15 @@ function missing(state, id) {
|
|
|
78
79
|
);
|
|
79
80
|
return connected ? `current: ${id}, which its account no longer offers` : `current: ${id}, whose account is not connected`;
|
|
80
81
|
}
|
|
81
|
-
function list(state, current, json) {
|
|
82
|
+
function list(state, current, json, locked) {
|
|
82
83
|
const listed = rows(state, current);
|
|
83
84
|
if (json) return ok(`${JSON.stringify(listed, null, 2)}
|
|
84
85
|
`);
|
|
85
86
|
const lines = listed.map(
|
|
86
87
|
(row) => `${row.current ? "*" : " "} ${row.id} ${row.label} ${row.account}`
|
|
87
88
|
);
|
|
88
|
-
if (
|
|
89
|
+
if (locked) lines.push(LOCKED_NOTE);
|
|
90
|
+
if (!listed.length) lines.push("no models: connect an account in Settings \u203A Accounts");
|
|
89
91
|
if (current.id && !listed.some((row) => row.current)) lines.push(missing(state, current.id));
|
|
90
92
|
return ok(`${lines.join("\n")}
|
|
91
93
|
`);
|
|
@@ -109,7 +111,7 @@ function refuse(options, state, wanted) {
|
|
|
109
111
|
const known = options.catalog.getModels(providerId);
|
|
110
112
|
if (disconnected && (!known.length || known.some((model) => model.id === modelId)))
|
|
111
113
|
return fail(
|
|
112
|
-
`${wanted} needs the ${disconnected.provider} account; connect it in Settings, then try again`
|
|
114
|
+
`${wanted} needs the ${disconnected.provider} account; connect it in Settings \u203A Accounts, then try again`
|
|
113
115
|
);
|
|
114
116
|
const ids = [
|
|
115
117
|
...state.models.map((choice) => choice.id),
|
|
@@ -168,13 +170,14 @@ function modelsCommand(options) {
|
|
|
168
170
|
await conversationOf(options.agents, caller, context),
|
|
169
171
|
context
|
|
170
172
|
);
|
|
171
|
-
return listing ? list(state, current, json) : show(state, current, json);
|
|
173
|
+
return listing ? list(state, current, json, options.locked?.() ?? false) : show(state, current, json);
|
|
172
174
|
} catch (error) {
|
|
173
175
|
return fail(error.message);
|
|
174
176
|
}
|
|
175
177
|
};
|
|
176
178
|
}
|
|
177
179
|
export {
|
|
180
|
+
LOCKED_NOTE,
|
|
178
181
|
USAGE,
|
|
179
182
|
closest,
|
|
180
183
|
modelsCommand
|
package/dist/models/index.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/models/index.ts"],
|
|
4
|
-
"sourcesContent": ["import type { Context } from '@earendil-works/chord';\nimport type { Models } from '@earendil-works/pi-ai/models';\nimport type { AgentChange, Conversation } from '@earendil-works/pi-durable';\nimport type { Agents } from '../agents.ts';\nimport { THINKING } from '../scoops/cli.ts';\nimport type { AgentSettings, ModelChoice, SettingsState } from '../services.ts';\n\nexport type Answer = { code: number; out: string };\n\nconst LEVELS = [...THINKING].join(', ');\n\nexport const USAGE = `usage:\n models [list] [--json] the models you can use, * marks the current one\n models current [--json] the current model\n models use <provider/model> [--thinking <level>] switch this agent's model, as the Settings picker does\n\nlevels: ${LEVELS}\nIn an agent's bash, models switches that cone or scoop; in a terminal, the active cone.\n`;\n\nexport interface ModelsOptions {\n agents: Agents;\n settings: Pick<AgentSettings, 'state'>;\n catalog: Pick<Models, 'getProviders' | 'getModels'>;\n}\n\nconst ok = (out: string): Answer => ({ code: 0, out });\nconst fail = (out: string, code = 1): Answer => ({ code, out: `models: ${out}\\n` });\n\nfunction distance(a: string, b: string): number {\n let previous = Array.from({ length: b.length + 1 }, (_, at) => at);\n for (let i = 1; i <= a.length; i++) {\n const row = [i];\n for (let j = 1; j <= b.length; j++)\n row[j] = Math.min(\n (previous[j] as number) + 1,\n (row[j - 1] as number) + 1,\n (previous[j - 1] as number) + (a[i - 1] === b[j - 1] ? 0 : 1)\n );\n previous = row;\n }\n return previous[b.length] as number;\n}\n\nexport function closest(wanted: string, ids: readonly string[], count = 3): string[] {\n const target = wanted.toLowerCase();\n const score = (id: string) => {\n const lower = id.toLowerCase();\n const tail = lower.slice(lower.indexOf('/') + 1);\n const near = Math.min(distance(target, lower), distance(target, tail));\n return lower.includes(target) || target.includes(tail) ? near - 1000 : near;\n };\n return [...new Set(ids)]\n .map((id) => ({ id, score: score(id) }))\n .sort((a, b) => a.score - b.score || a.id.localeCompare(b.id))\n .slice(0, count)\n .map((entry) => entry.id);\n}\n\nfunction agentOf(agents: Agents, caller: string | null): string {\n if (caller?.startsWith('cone:')) return caller.slice(5);\n return caller ?? agents.activeCone();\n}\n\nasync function conversationOf(agents: Agents, caller: string | null, context: Context) {\n const id = agentOf(agents, caller);\n const found = await agents.conversation(id, context);\n if (!found) throw new Error(`there is no agent ${id}`);\n return found;\n}\n\ntype Current = { id: string | null; thinking: string };\n\nasync function currentOf(conversation: Conversation, context: Context): Promise<Current> {\n const agent = await conversation.agent(context);\n return {\n id: agent.model ? `${agent.model.provider}/${agent.model.modelId}` : null,\n thinking: agent.thinkingLevel,\n };\n}\n\nfunction stateOf(options: ModelsOptions): SettingsState {\n return options.settings.state.value ?? { models: [], accounts: [] };\n}\n\nfunction account(state: SettingsState, choice: ModelChoice): string {\n const providerId = choice.id.slice(0, choice.id.indexOf('/'));\n const found = state.accounts.find((entry) => entry.id === providerId);\n return found?.identity ? `${choice.provider} (${found.identity})` : choice.provider;\n}\n\nfunction rows(state: SettingsState, current: Current) {\n return state.models.map((choice) => ({\n id: choice.id,\n label: choice.label,\n provider: choice.provider,\n account: account(state, choice),\n reasoning: choice.reasoning,\n contextWindow: choice.contextWindow,\n current: choice.id === current.id,\n }));\n}\n\nfunction missing(state: SettingsState, id: string): string {\n const providerId = id.slice(0, id.indexOf('/'));\n const connected = state.accounts.some(\n (entry) => entry.id === providerId && entry.status === 'connected'\n );\n return connected\n ? `current: ${id}, which its account no longer offers`\n : `current: ${id}, whose account is not connected`;\n}\n\nfunction list(state: SettingsState, current: Current, json: boolean): Answer {\n const listed = rows(state, current);\n if (json) return ok(`${JSON.stringify(listed, null, 2)}\\n`);\n const lines = listed.map(\n (row) => `${row.current ? '*' : ' '} ${row.id}\\t${row.label}\\t${row.account}`\n );\n if (!listed.length) lines.push('no models: connect an account in Settings');\n if (current.id && !listed.some((row) => row.current)) lines.push(missing(state, current.id));\n return ok(`${lines.join('\\n')}\\n`);\n}\n\nfunction show(state: SettingsState, current: Current, json: boolean): Answer {\n if (!json) return ok(`${current.id ?? 'none'}\\n`);\n const found = rows(state, current).find((row) => row.current);\n return ok(\n `${JSON.stringify({ id: current.id, thinking: current.thinking, label: found?.label ?? null, provider: found?.provider ?? null, available: Boolean(found) }, null, 2)}\\n`\n );\n}\n\nfunction refuse(options: ModelsOptions, state: SettingsState, wanted: string): Answer {\n const at = wanted.indexOf('/');\n const providerId = at > 0 ? wanted.slice(0, at) : '';\n const modelId = wanted.slice(at + 1);\n const disconnected = state.accounts.find(\n (entry) => entry.id === providerId && entry.status !== 'connected'\n );\n const known = options.catalog.getModels(providerId);\n if (disconnected && (!known.length || known.some((model) => model.id === modelId)))\n return fail(\n `${wanted} needs the ${disconnected.provider} account; connect it in Settings, then try again`\n );\n const ids = [\n ...state.models.map((choice) => choice.id),\n ...options.catalog\n .getProviders()\n .flatMap((provider) =>\n options.catalog.getModels(provider.id).map((model) => `${provider.id}/${model.id}`)\n ),\n ];\n const near = closest(wanted, ids);\n return fail(\n `there is no model ${wanted}${near.length ? `; the closest are ${near.join(', ')}` : ''}`\n );\n}\n\nasync function use(\n options: ModelsOptions,\n argv: readonly string[],\n caller: string | null,\n context: Context\n): Promise<Answer> {\n const rest: string[] = [];\n let thinking: string | undefined;\n for (let at = 0; at < argv.length; at++) {\n const arg = argv[at] as string;\n if (arg === '--thinking') {\n thinking = argv[++at];\n if (thinking === undefined) return fail('--thinking needs a level', 2);\n } else if (arg.startsWith('-')) return fail(`unknown option ${arg}`, 2);\n else rest.push(arg);\n }\n if (rest.length !== 1) return { code: 2, out: USAGE };\n if (thinking !== undefined && !THINKING.has(thinking))\n return fail(`--thinking must be one of ${LEVELS}`, 2);\n const wanted = rest[0] as string;\n const state = stateOf(options);\n const choice = state.models.find((entry) => entry.id === wanted);\n if (!choice) return refuse(options, state, wanted);\n const at = wanted.indexOf('/');\n const change: AgentChange = {\n model: { provider: wanted.slice(0, at), modelId: wanted.slice(at + 1) },\n ...(thinking ? { thinkingLevel: thinking as AgentChange['thinkingLevel'] } : {}),\n };\n const conversation = await conversationOf(options.agents, caller, context);\n await conversation.configure(change, context);\n const now = await currentOf(conversation, context);\n return ok(`now using ${now.id} (${choice.label}), thinking ${now.thinking}\\n`);\n}\n\nexport function modelsCommand(options: ModelsOptions) {\n return async (argv: readonly string[], caller: string | null, context: Context) => {\n try {\n const [verb = 'list', ...rest] = argv;\n if (verb === '--help' || verb === '-h' || verb === 'help') return ok(USAGE);\n if (verb === 'use') return await use(options, rest, caller, context);\n const listing = verb === 'list' || verb === '--json';\n if (!listing && verb !== 'current') return { code: 2, out: USAGE };\n const flags = verb === '--json' ? argv : rest;\n const unknown = flags.find((arg) => arg !== '--json');\n if (unknown) return { code: 2, out: USAGE };\n const json = flags.includes('--json');\n const state = stateOf(options);\n const current = await currentOf(\n await conversationOf(options.agents, caller, context),\n context\n );\n return listing
|
|
5
|
-
"mappings": "AAIA,SAAS,gBAAgB;AAKzB,MAAM,SAAS,CAAC,GAAG,QAAQ,EAAE,KAAK,IAAI;AAE/B,MAAM,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA,UAKX,MAAM;AAAA;AAAA;
|
|
4
|
+
"sourcesContent": ["import type { Context } from '@earendil-works/chord';\nimport type { Models } from '@earendil-works/pi-ai/models';\nimport type { AgentChange, Conversation } from '@earendil-works/pi-durable';\nimport type { Agents } from '../agents.ts';\nimport { THINKING } from '../scoops/cli.ts';\nimport type { AgentSettings, ModelChoice, SettingsState } from '../services.ts';\n\nexport type Answer = { code: number; out: string };\n\nconst LEVELS = [...THINKING].join(', ');\n\nexport const USAGE = `usage:\n models [list] [--json] the models you can use, * marks the current one\n models current [--json] the current model\n models use <provider/model> [--thinking <level>] switch this agent's model, as the Settings picker does\n\nlevels: ${LEVELS}\nIn an agent's bash, models switches that cone or scoop; in a terminal, the active cone.\n`;\n\nexport interface ModelsOptions {\n agents: Agents;\n settings: Pick<AgentSettings, 'state'>;\n catalog: Pick<Models, 'getProviders' | 'getModels'>;\n locked?: () => boolean;\n}\n\nexport const LOCKED_NOTE = 'the vault is locked: unlock it to use these accounts';\n\nconst ok = (out: string): Answer => ({ code: 0, out });\nconst fail = (out: string, code = 1): Answer => ({ code, out: `models: ${out}\\n` });\n\nfunction distance(a: string, b: string): number {\n let previous = Array.from({ length: b.length + 1 }, (_, at) => at);\n for (let i = 1; i <= a.length; i++) {\n const row = [i];\n for (let j = 1; j <= b.length; j++)\n row[j] = Math.min(\n (previous[j] as number) + 1,\n (row[j - 1] as number) + 1,\n (previous[j - 1] as number) + (a[i - 1] === b[j - 1] ? 0 : 1)\n );\n previous = row;\n }\n return previous[b.length] as number;\n}\n\nexport function closest(wanted: string, ids: readonly string[], count = 3): string[] {\n const target = wanted.toLowerCase();\n const score = (id: string) => {\n const lower = id.toLowerCase();\n const tail = lower.slice(lower.indexOf('/') + 1);\n const near = Math.min(distance(target, lower), distance(target, tail));\n return lower.includes(target) || target.includes(tail) ? near - 1000 : near;\n };\n return [...new Set(ids)]\n .map((id) => ({ id, score: score(id) }))\n .sort((a, b) => a.score - b.score || a.id.localeCompare(b.id))\n .slice(0, count)\n .map((entry) => entry.id);\n}\n\nfunction agentOf(agents: Agents, caller: string | null): string {\n if (caller?.startsWith('cone:')) return caller.slice(5);\n return caller ?? agents.activeCone();\n}\n\nasync function conversationOf(agents: Agents, caller: string | null, context: Context) {\n const id = agentOf(agents, caller);\n const found = await agents.conversation(id, context);\n if (!found) throw new Error(`there is no agent ${id}`);\n return found;\n}\n\ntype Current = { id: string | null; thinking: string };\n\nasync function currentOf(conversation: Conversation, context: Context): Promise<Current> {\n const agent = await conversation.agent(context);\n return {\n id: agent.model ? `${agent.model.provider}/${agent.model.modelId}` : null,\n thinking: agent.thinkingLevel,\n };\n}\n\nfunction stateOf(options: ModelsOptions): SettingsState {\n return options.settings.state.value ?? { models: [], accounts: [] };\n}\n\nfunction account(state: SettingsState, choice: ModelChoice): string {\n const providerId = choice.id.slice(0, choice.id.indexOf('/'));\n const found = state.accounts.find((entry) => entry.id === providerId);\n return found?.identity ? `${choice.provider} (${found.identity})` : choice.provider;\n}\n\nfunction rows(state: SettingsState, current: Current) {\n return state.models.map((choice) => ({\n id: choice.id,\n label: choice.label,\n provider: choice.provider,\n account: account(state, choice),\n reasoning: choice.reasoning,\n contextWindow: choice.contextWindow,\n current: choice.id === current.id,\n }));\n}\n\nfunction missing(state: SettingsState, id: string): string {\n const providerId = id.slice(0, id.indexOf('/'));\n const connected = state.accounts.some(\n (entry) => entry.id === providerId && entry.status === 'connected'\n );\n return connected\n ? `current: ${id}, which its account no longer offers`\n : `current: ${id}, whose account is not connected`;\n}\n\nfunction list(state: SettingsState, current: Current, json: boolean, locked: boolean): Answer {\n const listed = rows(state, current);\n if (json) return ok(`${JSON.stringify(listed, null, 2)}\\n`);\n const lines = listed.map(\n (row) => `${row.current ? '*' : ' '} ${row.id}\\t${row.label}\\t${row.account}`\n );\n if (locked) lines.push(LOCKED_NOTE);\n if (!listed.length) lines.push('no models: connect an account in Settings \u203A Accounts');\n if (current.id && !listed.some((row) => row.current)) lines.push(missing(state, current.id));\n return ok(`${lines.join('\\n')}\\n`);\n}\n\nfunction show(state: SettingsState, current: Current, json: boolean): Answer {\n if (!json) return ok(`${current.id ?? 'none'}\\n`);\n const found = rows(state, current).find((row) => row.current);\n return ok(\n `${JSON.stringify({ id: current.id, thinking: current.thinking, label: found?.label ?? null, provider: found?.provider ?? null, available: Boolean(found) }, null, 2)}\\n`\n );\n}\n\nfunction refuse(options: ModelsOptions, state: SettingsState, wanted: string): Answer {\n const at = wanted.indexOf('/');\n const providerId = at > 0 ? wanted.slice(0, at) : '';\n const modelId = wanted.slice(at + 1);\n const disconnected = state.accounts.find(\n (entry) => entry.id === providerId && entry.status !== 'connected'\n );\n const known = options.catalog.getModels(providerId);\n if (disconnected && (!known.length || known.some((model) => model.id === modelId)))\n return fail(\n `${wanted} needs the ${disconnected.provider} account; connect it in Settings \u203A Accounts, then try again`\n );\n const ids = [\n ...state.models.map((choice) => choice.id),\n ...options.catalog\n .getProviders()\n .flatMap((provider) =>\n options.catalog.getModels(provider.id).map((model) => `${provider.id}/${model.id}`)\n ),\n ];\n const near = closest(wanted, ids);\n return fail(\n `there is no model ${wanted}${near.length ? `; the closest are ${near.join(', ')}` : ''}`\n );\n}\n\nasync function use(\n options: ModelsOptions,\n argv: readonly string[],\n caller: string | null,\n context: Context\n): Promise<Answer> {\n const rest: string[] = [];\n let thinking: string | undefined;\n for (let at = 0; at < argv.length; at++) {\n const arg = argv[at] as string;\n if (arg === '--thinking') {\n thinking = argv[++at];\n if (thinking === undefined) return fail('--thinking needs a level', 2);\n } else if (arg.startsWith('-')) return fail(`unknown option ${arg}`, 2);\n else rest.push(arg);\n }\n if (rest.length !== 1) return { code: 2, out: USAGE };\n if (thinking !== undefined && !THINKING.has(thinking))\n return fail(`--thinking must be one of ${LEVELS}`, 2);\n const wanted = rest[0] as string;\n const state = stateOf(options);\n const choice = state.models.find((entry) => entry.id === wanted);\n if (!choice) return refuse(options, state, wanted);\n const at = wanted.indexOf('/');\n const change: AgentChange = {\n model: { provider: wanted.slice(0, at), modelId: wanted.slice(at + 1) },\n ...(thinking ? { thinkingLevel: thinking as AgentChange['thinkingLevel'] } : {}),\n };\n const conversation = await conversationOf(options.agents, caller, context);\n await conversation.configure(change, context);\n const now = await currentOf(conversation, context);\n return ok(`now using ${now.id} (${choice.label}), thinking ${now.thinking}\\n`);\n}\n\nexport function modelsCommand(options: ModelsOptions) {\n return async (argv: readonly string[], caller: string | null, context: Context) => {\n try {\n const [verb = 'list', ...rest] = argv;\n if (verb === '--help' || verb === '-h' || verb === 'help') return ok(USAGE);\n if (verb === 'use') return await use(options, rest, caller, context);\n const listing = verb === 'list' || verb === '--json';\n if (!listing && verb !== 'current') return { code: 2, out: USAGE };\n const flags = verb === '--json' ? argv : rest;\n const unknown = flags.find((arg) => arg !== '--json');\n if (unknown) return { code: 2, out: USAGE };\n const json = flags.includes('--json');\n const state = stateOf(options);\n const current = await currentOf(\n await conversationOf(options.agents, caller, context),\n context\n );\n return listing\n ? list(state, current, json, options.locked?.() ?? false)\n : show(state, current, json);\n } catch (error) {\n return fail((error as Error).message);\n }\n };\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["at"]
|
|
7
7
|
}
|
package/dist/monitor/index.js
CHANGED
|
@@ -251,10 +251,7 @@ class Session {
|
|
|
251
251
|
at: this.#settings.now(),
|
|
252
252
|
agentId: conversations(this.#options.agents.state()).get(task.conversationId) ?? null,
|
|
253
253
|
kind: "task",
|
|
254
|
-
message: redacted(
|
|
255
|
-
outcome.status === "faulted" ? outcome.error.message : outcome.reason,
|
|
256
|
-
this.#settings.secrets()
|
|
257
|
-
)
|
|
254
|
+
message: redacted(outcome.status === "faulted" ? outcome.error.message : outcome.reason)
|
|
258
255
|
});
|
|
259
256
|
return true;
|
|
260
257
|
}
|
|
@@ -271,7 +268,6 @@ class Session {
|
|
|
271
268
|
return at;
|
|
272
269
|
}
|
|
273
270
|
#agent(agent, view, tools) {
|
|
274
|
-
const secrets = this.#settings.secrets();
|
|
275
271
|
const liveDoc = view?.docs["pi.live"];
|
|
276
272
|
for (const slot of liveDoc?.tools ?? [])
|
|
277
273
|
if (slot.taskId !== void 0) tools.set(String(slot.taskId), slot.name);
|
|
@@ -281,7 +277,7 @@ class Session {
|
|
|
281
277
|
const retry = generation?.retry ? {
|
|
282
278
|
attempt: generation.attempt,
|
|
283
279
|
since: this.#since(`retry:${agent.id}`),
|
|
284
|
-
error: redacted(generation.retry.error
|
|
280
|
+
error: redacted(generation.retry.error)
|
|
285
281
|
} : null;
|
|
286
282
|
if (retry)
|
|
287
283
|
this.#problem({
|
|
@@ -292,7 +288,7 @@ class Session {
|
|
|
292
288
|
message: retry.error
|
|
293
289
|
});
|
|
294
290
|
const last = lastAssistant(view);
|
|
295
|
-
const failed = last?.message.stopReason === "error" ? redacted(last.message.errorMessage || "error"
|
|
291
|
+
const failed = last?.message.stopReason === "error" ? redacted(last.message.errorMessage || "error") : null;
|
|
296
292
|
if (failed && last)
|
|
297
293
|
this.#problem({
|
|
298
294
|
id: `turn:${last.id}`,
|
|
@@ -344,7 +340,7 @@ class Session {
|
|
|
344
340
|
pgid,
|
|
345
341
|
user: uid === void 0 ? null : this.#users.get(uid) ?? (uid === 0 ? "root" : `uid ${uid}`),
|
|
346
342
|
agentId: groups.get(pgid) ?? null,
|
|
347
|
-
command: commandLine(argv
|
|
343
|
+
command: commandLine(argv),
|
|
348
344
|
state: zombie ? "Z" : "S",
|
|
349
345
|
started: entry.started ?? 0,
|
|
350
346
|
zombie: zombie ? this.#since(`zombie:${entry.pid}`) : null,
|
|
@@ -404,8 +400,7 @@ function createMonitor(options) {
|
|
|
404
400
|
psMs: options.psMs ?? PS_MS,
|
|
405
401
|
psTimeoutMs: options.psTimeoutMs ?? PS_TIMEOUT_MS,
|
|
406
402
|
throttleMs: options.throttleMs ?? THROTTLE_MS,
|
|
407
|
-
usageMs: options.usageMs ?? USAGE_MS
|
|
408
|
-
secrets: () => options.secrets?.() ?? []
|
|
403
|
+
usageMs: options.usageMs ?? USAGE_MS
|
|
409
404
|
};
|
|
410
405
|
const { now, timers, context } = settings;
|
|
411
406
|
const ttlMs = options.ttlMs ?? TTL_MS;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/monitor/index.ts"],
|
|
4
|
-
"sourcesContent": ["import {\n type Context,\n type JsonValue,\n type ReplicatedState,\n replicatedState,\n} from '@earendil-works/chord';\nimport { BACKGROUND_CONTEXT } from '@earendil-works/chord/context';\nimport type {\n CommitPublication,\n ConversationView,\n Harness,\n TaskGraph,\n TaskGraphNode,\n TaskGraphWatch,\n TaskRecord,\n UsageState,\n} from '@earendil-works/pi-durable';\nimport { type AgentsState, live } from '../agents.ts';\nimport { contextTokens } from '../context.ts';\nimport type {\n MonitorAgent,\n MonitorFeed,\n MonitorLease,\n MonitorProblem,\n MonitorProcess,\n MonitorTask,\n} from '../services.ts';\nimport { commandLine, program, redacted } from './redact.ts';\n\nexport interface PsEntry {\n pid: number;\n ppid?: number;\n pgid?: number;\n argv?: readonly string[];\n tty?: unknown;\n started?: number;\n state?: string;\n uid?: number;\n rss?: number;\n utime?: number;\n stime?: number;\n}\n\nexport interface CpuMark {\n started: number;\n total: number;\n at: number;\n}\n\nexport interface CpuReading {\n marks: Map<number, CpuMark>;\n shares: Map<number, number | null>;\n}\n\nfunction timed(entry: PsEntry): entry is PsEntry & { utime: number; stime: number } {\n return typeof entry.utime === 'number' && typeof entry.stime === 'number';\n}\n\nexport function cpuShares(\n entries: readonly PsEntry[],\n previous: ReadonlyMap<number, CpuMark>,\n at: number\n): CpuReading {\n const marks = new Map<number, CpuMark>();\n const shares = new Map<number, number | null>();\n for (const entry of entries) {\n if (!timed(entry)) continue;\n const mark = { started: entry.started ?? 0, total: entry.utime + entry.stime, at };\n const last = previous.get(entry.pid);\n marks.set(entry.pid, mark);\n shares.set(\n entry.pid,\n last && last.started === mark.started && mark.total >= last.total && at > last.at\n ? Math.round(((mark.total - last.total) / (at - last.at)) * 1000) / 1000\n : null\n );\n }\n return { marks, shares };\n}\n\nexport function agentCpu(processes: readonly MonitorProcess[], agentId: string): number | null {\n if (!processes.some((row) => typeof row.cpu === 'number')) return null;\n let sum = 0;\n for (const row of processes) if (row.agentId === agentId) sum += row.cpu ?? 0;\n return Math.round(sum * 1000) / 1000;\n}\n\nexport interface Timers {\n set(run: () => void, ms: number): unknown;\n clear(handle: unknown): void;\n}\n\nexport interface MonitorOptions {\n harness: Pick<Harness, 'watchTaskGraph' | 'usage' | 'subscribeCommits' | 'inspect'>;\n agents: { state(): Readonly<AgentsState>; onChange(listener: () => void): () => void };\n views: ReplicatedState<Record<string, ConversationView>>;\n kernel?: { ps?(): Promise<readonly PsEntry[]> };\n groups?: { owned(owner: number): number[] };\n users?: () => Promise<readonly { name: string; uid: number }[]>;\n secrets?: () => readonly string[];\n now?: () => number;\n timers?: Timers;\n ttlMs?: number;\n psMs?: number;\n psTimeoutMs?: number;\n throttleMs?: number;\n usageMs?: number;\n context?: Context;\n}\n\nexport interface Monitor {\n readonly state: ReplicatedState<MonitorFeed>;\n readonly viewState: ReplicatedState<MonitorFeed>;\n open(lease: string | null, resync: boolean, context: Context): Promise<MonitorLease>;\n close(lease: string, context: Context): Promise<void>;\n active(): boolean;\n dispose(): Promise<void>;\n}\n\nexport const TTL_MS = 30000;\nexport const PS_MS = 2000;\nexport const PS_TIMEOUT_MS = 5000;\nexport const THROTTLE_MS = 1000;\nexport const USAGE_MS = 2000;\nexport const PROBLEMS_MAX = 50;\n\nexport const globalTimers: Timers = {\n set: (run, ms) => setTimeout(run, ms),\n clear: (handle) => clearTimeout(handle as ReturnType<typeof setTimeout>),\n};\n\nexport function emptyFeed(): MonitorFeed {\n return {\n open: false,\n at: 0,\n usage: null,\n agents: [],\n tasks: [],\n processes: null,\n kernel: 'checking',\n problems: [],\n paused: false,\n };\n}\n\ninterface Live {\n run?: unknown;\n generation?: { attempt: number; retry?: { at: number; error: string } };\n tools?: { name: string; status: string; taskId?: unknown }[];\n}\n\ninterface ModelMessage {\n stopReason?: string;\n errorMessage?: string;\n}\n\nexport function totals(usage: UsageState): { tokens: number; cost: number; free: boolean } {\n let tokens = 0;\n let cost = 0;\n for (const bucket of [usage.models, usage.tools])\n for (const entry of Object.values(bucket)) {\n tokens += entry.totalTokens ?? 0;\n cost += entry.cost?.total ?? 0;\n }\n return { tokens, cost, free: cost === 0 };\n}\n\nfunction phaseOf(node: TaskGraphNode): string {\n return 'phase' in node.state ? node.state.phase : node.state.outcome;\n}\n\nfunction lastAssistant(view: ConversationView | undefined) {\n const entries = view?.entries ?? [];\n for (let at = entries.length - 1; at >= 0; at--) {\n const entry = entries[at] as (typeof entries)[number];\n if (entry.kind === 'pi.assistant')\n return { id: String(entry.id), message: (entry.model?.[0] ?? {}) as ModelMessage };\n }\n return undefined;\n}\n\nfunction conversations(state: Readonly<AgentsState>): Map<number, string> {\n const out = new Map<number, string>();\n for (const [id, scoop] of Object.entries(state.scoops)) out.set(scoop.conversation, id);\n for (const [id, cone] of Object.entries(state.cones)) out.set(cone.conversation, id);\n return out;\n}\n\nfunction liveAgents(state: Readonly<AgentsState>) {\n const cones = Object.entries(state.cones).map(([id, cone]) => ({\n id,\n name: cone.name,\n kind: 'cone' as const,\n parentId: null,\n conversation: cone.conversation,\n }));\n const scoops = Object.entries(state.scoops)\n .filter(([, scoop]) => live(scoop))\n .map(([id, scoop]) => ({\n id,\n name: scoop.name,\n kind: 'scoop' as const,\n parentId: scoop.parent,\n conversation: scoop.conversation,\n }));\n return [...cones, ...scoops];\n}\n\nexport function narrowed(feed: MonitorFeed, programs: ReadonlyMap<number, string>): MonitorFeed {\n if (!feed.processes) return feed;\n return {\n ...feed,\n processes: feed.processes.map((row) => ({ ...row, command: programs.get(row.pid) ?? '' })),\n };\n}\n\ninterface Settings {\n now: () => number;\n timers: Timers;\n context: Context;\n psMs: number;\n psTimeoutMs: number;\n throttleMs: number;\n usageMs: number;\n secrets: () => readonly string[];\n}\n\ntype Agent = ReturnType<typeof liveAgents>[number];\n\nclass Session {\n stopped = false;\n readonly #options: MonitorOptions;\n readonly #settings: Settings;\n readonly #publish: (feed: MonitorFeed, view: MonitorFeed) => void;\n readonly #off: (() => void)[] = [];\n readonly #handles = new Set<unknown>();\n #watch: TaskGraphWatch | undefined;\n #graph: TaskGraph = { tasks: {} };\n #usage: UsageState | null = null;\n #processes: readonly PsEntry[] | null = null;\n #cpu: CpuReading = { marks: new Map(), shares: new Map() };\n #kernel: MonitorFeed['kernel'];\n #users = new Map<number, string>();\n #paused = false;\n #problems: MonitorProblem[] = [];\n #seen = new Map<string, number>();\n #next = new Map<string, number>();\n #build: unknown;\n #usageTimer: unknown;\n #lastBuild = Number.NEGATIVE_INFINITY;\n #last = '';\n\n constructor(\n options: MonitorOptions,\n settings: Settings,\n publish: (feed: MonitorFeed, view: MonitorFeed) => void\n ) {\n this.#options = options;\n this.#settings = settings;\n this.#publish = publish;\n this.#kernel = options.kernel?.ps ? 'checking' : 'unreachable';\n }\n\n start(): void {\n const options = this.#options;\n this.#off.push(\n options.harness.subscribeCommits((publication) => this.#commit(publication)),\n options.agents.onChange(() => this.schedule()),\n options.views.subscribe(() => this.schedule())\n );\n void options.harness.watchTaskGraph(this.#settings.context).then(\n (watch) => this.#watching(watch),\n () => undefined\n );\n void options.users?.().then(\n (list) => {\n this.#users = new Map(list.map((user) => [user.uid, user.name]));\n this.schedule();\n },\n () => undefined\n );\n this.#poll();\n this.refresh();\n }\n\n stop(): void {\n this.stopped = true;\n for (const off of this.#off) off();\n for (const handle of this.#handles) this.#settings.timers.clear(handle);\n this.#handles.clear();\n void this.#watch?.stop();\n }\n\n refresh(): void {\n void this.#readUsage();\n void this.#options.harness.inspect(this.#settings.context).then(\n (inspection) => {\n this.#paused = inspection.scheduling === 'paused';\n this.schedule();\n },\n () => undefined\n );\n this.schedule();\n }\n\n schedule(): void {\n if (this.stopped || this.#build !== undefined) return;\n const wait = Math.max(0, this.#lastBuild + this.#settings.throttleMs - this.#settings.now());\n this.#build = this.#later(() => {\n this.#build = undefined;\n this.#emit();\n }, wait);\n }\n\n #later(task: () => void, ms: number): unknown {\n if (this.stopped) return undefined;\n const handle = this.#settings.timers.set(() => {\n this.#handles.delete(handle);\n if (!this.stopped) task();\n }, ms);\n this.#handles.add(handle);\n return handle;\n }\n\n #watching(watch: TaskGraphWatch): void {\n if (this.stopped) {\n void watch.stop();\n return;\n }\n this.#watch = watch;\n this.#graph = watch.value;\n this.schedule();\n watch.start(async (graph) => {\n this.#graph = graph;\n this.schedule();\n });\n }\n\n #readUsage(): Promise<void> {\n return this.#options.harness.usage(this.#settings.context).then(\n (usage) => {\n this.#usage = usage;\n this.schedule();\n },\n () => undefined\n );\n }\n\n #poll(): void {\n const kernel = this.#options.kernel;\n if (!kernel?.ps) return;\n let settled = false;\n const settle = (entries: readonly PsEntry[] | null) => {\n if (settled || this.stopped) return;\n settled = true;\n this.#settings.timers.clear(timeout);\n this.#handles.delete(timeout);\n this.#processes = entries;\n if (entries) this.#cpu = cpuShares(entries, this.#cpu.marks, this.#settings.now());\n this.#kernel = entries ? 'ok' : 'unreachable';\n this.schedule();\n this.#later(() => this.#poll(), this.#settings.psMs);\n };\n const timeout = this.#later(() => settle(null), this.#settings.psTimeoutMs);\n kernel.ps().then(settle, () => settle(null));\n }\n\n #problem(entry: MonitorProblem): void {\n if (this.#problems.some((known) => known.id === entry.id)) return;\n this.#problems.unshift(entry);\n this.#problems.length = Math.min(this.#problems.length, PROBLEMS_MAX);\n }\n\n #commit(publication: CommitPublication): void {\n let changed = false;\n for (const change of publication.changes) {\n if (change.type === 'task') changed = this.#failed(change.value) || changed;\n else if (change.type === 'document' && change.record.kind === 'pi.usage')\n this.#usageChanged();\n }\n if (changed) this.schedule();\n }\n\n #failed(task: TaskRecord<JsonValue, JsonValue, JsonValue>): boolean {\n if (task.state.status !== 'terminal') return false;\n const outcome = task.state.outcome;\n if (outcome.status !== 'faulted' && outcome.status !== 'orphaned') return false;\n this.#problem({\n id: `task:${task.id}`,\n at: this.#settings.now(),\n agentId: conversations(this.#options.agents.state()).get(task.conversationId) ?? null,\n kind: 'task',\n message: redacted(\n outcome.status === 'faulted' ? outcome.error.message : outcome.reason,\n this.#settings.secrets()\n ),\n });\n return true;\n }\n\n #usageChanged(): void {\n if (this.#usageTimer !== undefined) return;\n this.#usageTimer = this.#later(() => {\n this.#usageTimer = undefined;\n void this.#readUsage();\n }, this.#settings.usageMs);\n }\n\n #since(key: string): number {\n const at = this.#seen.get(key) ?? this.#settings.now();\n this.#next.set(key, at);\n return at;\n }\n\n #agent(agent: Agent, view: ConversationView | undefined, tools: Map<string, string>) {\n const secrets = this.#settings.secrets();\n const liveDoc = view?.docs['pi.live'] as Live | undefined;\n for (const slot of liveDoc?.tools ?? [])\n if (slot.taskId !== undefined) tools.set(String(slot.taskId), slot.name);\n const inbox = view?.docs['pi.inbox'] as { items?: unknown[] } | undefined;\n const doc = view?.docs['pi.agent'] as\n | { model?: { provider: string; modelId: string } }\n | undefined;\n const generation = liveDoc?.generation;\n const retry = generation?.retry\n ? {\n attempt: generation.attempt,\n since: this.#since(`retry:${agent.id}`),\n error: redacted(generation.retry.error, secrets),\n }\n : null;\n if (retry)\n this.#problem({\n id: `retry:${agent.id}:${retry.since}`,\n at: retry.since,\n agentId: agent.id,\n kind: 'retry',\n message: retry.error,\n });\n const last = lastAssistant(view);\n const failed =\n last?.message.stopReason === 'error'\n ? redacted(last.message.errorMessage || 'error', secrets)\n : null;\n if (failed && last)\n this.#problem({\n id: `turn:${last.id}`,\n at: this.#settings.now(),\n agentId: agent.id,\n kind: 'turn',\n message: failed,\n });\n return {\n id: agent.id,\n name: agent.name,\n kind: agent.kind,\n parentId: agent.parentId,\n model: doc?.model ? `${doc.model.provider}/${doc.model.modelId}` : null,\n running: Boolean(liveDoc?.run),\n queued: inbox?.items?.length ?? 0,\n tool: liveDoc?.tools?.find((slot) => slot.status === 'running')?.name ?? null,\n retry,\n failed,\n context: contextTokens(view),\n };\n }\n\n #task(node: TaskGraphNode, owners: Map<number, string>, details: Map<string, string>) {\n const id = String(node.id);\n const status = node.state.status;\n return {\n id,\n kind: node.kind,\n detail: details.get(id) ?? null,\n agentId: owners.get(node.conversationId) ?? null,\n owner: node.owner === undefined ? null : String(node.owner),\n status,\n phase: phaseOf(node),\n background: node.background,\n aborting: node.abortRequested ? this.#since(`abort:${id}`) : null,\n since: this.#since(`task:${id}:${status}`),\n waits: node.state.status === 'waiting' ? node.state.on.length : 0,\n };\n }\n\n #process(entry: PsEntry, groups: Map<number, string>, programs: Map<number, string>) {\n const argv = entry.argv ?? [];\n const pgid = entry.pgid ?? entry.pid;\n const zombie = entry.state === 'Z';\n programs.set(entry.pid, program(argv));\n const uid = entry.uid;\n return {\n pid: entry.pid,\n ppid: entry.ppid ?? 0,\n pgid,\n user:\n uid === undefined ? null : (this.#users.get(uid) ?? (uid === 0 ? 'root' : `uid ${uid}`)),\n agentId: groups.get(pgid) ?? null,\n command: commandLine(argv, this.#settings.secrets()),\n state: zombie ? ('Z' as const) : ('S' as const),\n started: entry.started ?? 0,\n zombie: zombie ? this.#since(`zombie:${entry.pid}`) : null,\n tty: Boolean(entry.tty),\n rss: typeof entry.rss === 'number' ? entry.rss : null,\n ...(timed(entry)\n ? { utime: entry.utime, stime: entry.stime, cpu: this.#cpu.shares.get(entry.pid) ?? null }\n : {}),\n };\n }\n\n #emit(): void {\n this.#lastBuild = this.#settings.now();\n this.#next = new Map();\n const registry = this.#options.agents.state();\n const views = this.#options.views.value ?? {};\n const agents = liveAgents(registry);\n const details = new Map<string, string>();\n const rows: MonitorAgent[] = agents.map((agent) =>\n this.#agent(agent, views[agent.id], details)\n );\n for (const scoop of Object.values(registry.scoops))\n details.set(String(scoop.anchor), scoop.name);\n const owners = conversations(registry);\n const tasks: MonitorTask[] = Object.values(this.#graph.tasks).map((node) =>\n this.#task(node, owners, details)\n );\n const groups = new Map<number, string>();\n for (const agent of agents)\n for (const pgid of this.#options.groups?.owned(agent.conversation) ?? [])\n groups.set(pgid, agent.id);\n const programs = new Map<number, string>();\n const entries = this.#processes;\n const processes: MonitorProcess[] | null =\n entries?.map((entry) => this.#process(entry, groups, programs)) ?? null;\n if (entries?.some(timed))\n for (const row of rows) row.cpu = agentCpu(processes as MonitorProcess[], row.id);\n this.#seen = this.#next;\n const feed: MonitorFeed = {\n open: true,\n at: this.#lastBuild,\n usage: this.#usage ? totals(this.#usage) : null,\n agents: rows,\n tasks,\n processes,\n kernel: this.#kernel,\n problems: [...this.#problems],\n paused: this.#paused,\n };\n const key = JSON.stringify({ ...feed, at: 0 });\n if (key === this.#last) return;\n this.#last = key;\n this.#publish(feed, narrowed(feed, programs));\n }\n}\n\nexport function createMonitor(options: MonitorOptions): Monitor {\n const settings: Settings = {\n now: options.now ?? Date.now,\n timers: options.timers ?? globalTimers,\n context: options.context ?? BACKGROUND_CONTEXT,\n psMs: options.psMs ?? PS_MS,\n psTimeoutMs: options.psTimeoutMs ?? PS_TIMEOUT_MS,\n throttleMs: options.throttleMs ?? THROTTLE_MS,\n usageMs: options.usageMs ?? USAGE_MS,\n secrets: () => options.secrets?.() ?? [],\n };\n const { now, timers, context } = settings;\n const ttlMs = options.ttlMs ?? TTL_MS;\n const state = replicatedState<MonitorFeed>(emptyFeed());\n const viewState = replicatedState<MonitorFeed>(emptyFeed());\n const leases = new Map<string, number>();\n let session: Session | undefined;\n let sweep: unknown;\n const publish = (feed: MonitorFeed, view: MonitorFeed) => {\n state.replace(context, feed);\n viewState.replace(context, view);\n };\n const stop = () => {\n if (sweep !== undefined) timers.clear(sweep);\n sweep = undefined;\n const current = session;\n if (!current) return;\n session = undefined;\n current.stop();\n publish(\n { ...(state.value as MonitorFeed), open: false },\n { ...(viewState.value as MonitorFeed), open: false }\n );\n };\n const arm = () => {\n if (sweep !== undefined) timers.clear(sweep);\n sweep = timers.set(expire, Math.max(0, Math.min(...leases.values()) - now()));\n };\n const expire = () => {\n sweep = undefined;\n const at = now();\n for (const [lease, until] of [...leases]) if (until <= at) leases.delete(lease);\n if (leases.size) arm();\n else stop();\n };\n return {\n state,\n viewState,\n async open(lease, resync) {\n const id = lease ?? crypto.randomUUID();\n leases.set(id, now() + ttlMs);\n arm();\n if (!session) {\n session = new Session(options, settings, publish);\n session.start();\n } else if (resync) session.refresh();\n return { lease: id, ttlMs };\n },\n async close(lease) {\n if (!leases.delete(lease)) return;\n if (leases.size) arm();\n else stop();\n },\n active: () => session !== undefined,\n async dispose() {\n leases.clear();\n stop();\n },\n };\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["import {\n type Context,\n type JsonValue,\n type ReplicatedState,\n replicatedState,\n} from '@earendil-works/chord';\nimport { BACKGROUND_CONTEXT } from '@earendil-works/chord/context';\nimport type {\n CommitPublication,\n ConversationView,\n Harness,\n TaskGraph,\n TaskGraphNode,\n TaskGraphWatch,\n TaskRecord,\n UsageState,\n} from '@earendil-works/pi-durable';\nimport { type AgentsState, live } from '../agents.ts';\nimport { contextTokens } from '../context.ts';\nimport type {\n MonitorAgent,\n MonitorFeed,\n MonitorLease,\n MonitorProblem,\n MonitorProcess,\n MonitorTask,\n} from '../services.ts';\nimport { commandLine, program, redacted } from './redact.ts';\n\nexport interface PsEntry {\n pid: number;\n ppid?: number;\n pgid?: number;\n argv?: readonly string[];\n tty?: unknown;\n started?: number;\n state?: string;\n uid?: number;\n rss?: number;\n utime?: number;\n stime?: number;\n}\n\nexport interface CpuMark {\n started: number;\n total: number;\n at: number;\n}\n\nexport interface CpuReading {\n marks: Map<number, CpuMark>;\n shares: Map<number, number | null>;\n}\n\nfunction timed(entry: PsEntry): entry is PsEntry & { utime: number; stime: number } {\n return typeof entry.utime === 'number' && typeof entry.stime === 'number';\n}\n\nexport function cpuShares(\n entries: readonly PsEntry[],\n previous: ReadonlyMap<number, CpuMark>,\n at: number\n): CpuReading {\n const marks = new Map<number, CpuMark>();\n const shares = new Map<number, number | null>();\n for (const entry of entries) {\n if (!timed(entry)) continue;\n const mark = { started: entry.started ?? 0, total: entry.utime + entry.stime, at };\n const last = previous.get(entry.pid);\n marks.set(entry.pid, mark);\n shares.set(\n entry.pid,\n last && last.started === mark.started && mark.total >= last.total && at > last.at\n ? Math.round(((mark.total - last.total) / (at - last.at)) * 1000) / 1000\n : null\n );\n }\n return { marks, shares };\n}\n\nexport function agentCpu(processes: readonly MonitorProcess[], agentId: string): number | null {\n if (!processes.some((row) => typeof row.cpu === 'number')) return null;\n let sum = 0;\n for (const row of processes) if (row.agentId === agentId) sum += row.cpu ?? 0;\n return Math.round(sum * 1000) / 1000;\n}\n\nexport interface Timers {\n set(run: () => void, ms: number): unknown;\n clear(handle: unknown): void;\n}\n\nexport interface MonitorOptions {\n harness: Pick<Harness, 'watchTaskGraph' | 'usage' | 'subscribeCommits' | 'inspect'>;\n agents: { state(): Readonly<AgentsState>; onChange(listener: () => void): () => void };\n views: ReplicatedState<Record<string, ConversationView>>;\n kernel?: { ps?(): Promise<readonly PsEntry[]> };\n groups?: { owned(owner: number): number[] };\n users?: () => Promise<readonly { name: string; uid: number }[]>;\n now?: () => number;\n timers?: Timers;\n ttlMs?: number;\n psMs?: number;\n psTimeoutMs?: number;\n throttleMs?: number;\n usageMs?: number;\n context?: Context;\n}\n\nexport interface Monitor {\n readonly state: ReplicatedState<MonitorFeed>;\n readonly viewState: ReplicatedState<MonitorFeed>;\n open(lease: string | null, resync: boolean, context: Context): Promise<MonitorLease>;\n close(lease: string, context: Context): Promise<void>;\n active(): boolean;\n dispose(): Promise<void>;\n}\n\nexport const TTL_MS = 30000;\nexport const PS_MS = 2000;\nexport const PS_TIMEOUT_MS = 5000;\nexport const THROTTLE_MS = 1000;\nexport const USAGE_MS = 2000;\nexport const PROBLEMS_MAX = 50;\n\nexport const globalTimers: Timers = {\n set: (run, ms) => setTimeout(run, ms),\n clear: (handle) => clearTimeout(handle as ReturnType<typeof setTimeout>),\n};\n\nexport function emptyFeed(): MonitorFeed {\n return {\n open: false,\n at: 0,\n usage: null,\n agents: [],\n tasks: [],\n processes: null,\n kernel: 'checking',\n problems: [],\n paused: false,\n };\n}\n\ninterface Live {\n run?: unknown;\n generation?: { attempt: number; retry?: { at: number; error: string } };\n tools?: { name: string; status: string; taskId?: unknown }[];\n}\n\ninterface ModelMessage {\n stopReason?: string;\n errorMessage?: string;\n}\n\nexport function totals(usage: UsageState): { tokens: number; cost: number; free: boolean } {\n let tokens = 0;\n let cost = 0;\n for (const bucket of [usage.models, usage.tools])\n for (const entry of Object.values(bucket)) {\n tokens += entry.totalTokens ?? 0;\n cost += entry.cost?.total ?? 0;\n }\n return { tokens, cost, free: cost === 0 };\n}\n\nfunction phaseOf(node: TaskGraphNode): string {\n return 'phase' in node.state ? node.state.phase : node.state.outcome;\n}\n\nfunction lastAssistant(view: ConversationView | undefined) {\n const entries = view?.entries ?? [];\n for (let at = entries.length - 1; at >= 0; at--) {\n const entry = entries[at] as (typeof entries)[number];\n if (entry.kind === 'pi.assistant')\n return { id: String(entry.id), message: (entry.model?.[0] ?? {}) as ModelMessage };\n }\n return undefined;\n}\n\nfunction conversations(state: Readonly<AgentsState>): Map<number, string> {\n const out = new Map<number, string>();\n for (const [id, scoop] of Object.entries(state.scoops)) out.set(scoop.conversation, id);\n for (const [id, cone] of Object.entries(state.cones)) out.set(cone.conversation, id);\n return out;\n}\n\nfunction liveAgents(state: Readonly<AgentsState>) {\n const cones = Object.entries(state.cones).map(([id, cone]) => ({\n id,\n name: cone.name,\n kind: 'cone' as const,\n parentId: null,\n conversation: cone.conversation,\n }));\n const scoops = Object.entries(state.scoops)\n .filter(([, scoop]) => live(scoop))\n .map(([id, scoop]) => ({\n id,\n name: scoop.name,\n kind: 'scoop' as const,\n parentId: scoop.parent,\n conversation: scoop.conversation,\n }));\n return [...cones, ...scoops];\n}\n\nexport function narrowed(feed: MonitorFeed, programs: ReadonlyMap<number, string>): MonitorFeed {\n if (!feed.processes) return feed;\n return {\n ...feed,\n processes: feed.processes.map((row) => ({ ...row, command: programs.get(row.pid) ?? '' })),\n };\n}\n\ninterface Settings {\n now: () => number;\n timers: Timers;\n context: Context;\n psMs: number;\n psTimeoutMs: number;\n throttleMs: number;\n usageMs: number;\n}\n\ntype Agent = ReturnType<typeof liveAgents>[number];\n\nclass Session {\n stopped = false;\n readonly #options: MonitorOptions;\n readonly #settings: Settings;\n readonly #publish: (feed: MonitorFeed, view: MonitorFeed) => void;\n readonly #off: (() => void)[] = [];\n readonly #handles = new Set<unknown>();\n #watch: TaskGraphWatch | undefined;\n #graph: TaskGraph = { tasks: {} };\n #usage: UsageState | null = null;\n #processes: readonly PsEntry[] | null = null;\n #cpu: CpuReading = { marks: new Map(), shares: new Map() };\n #kernel: MonitorFeed['kernel'];\n #users = new Map<number, string>();\n #paused = false;\n #problems: MonitorProblem[] = [];\n #seen = new Map<string, number>();\n #next = new Map<string, number>();\n #build: unknown;\n #usageTimer: unknown;\n #lastBuild = Number.NEGATIVE_INFINITY;\n #last = '';\n\n constructor(\n options: MonitorOptions,\n settings: Settings,\n publish: (feed: MonitorFeed, view: MonitorFeed) => void\n ) {\n this.#options = options;\n this.#settings = settings;\n this.#publish = publish;\n this.#kernel = options.kernel?.ps ? 'checking' : 'unreachable';\n }\n\n start(): void {\n const options = this.#options;\n this.#off.push(\n options.harness.subscribeCommits((publication) => this.#commit(publication)),\n options.agents.onChange(() => this.schedule()),\n options.views.subscribe(() => this.schedule())\n );\n void options.harness.watchTaskGraph(this.#settings.context).then(\n (watch) => this.#watching(watch),\n () => undefined\n );\n void options.users?.().then(\n (list) => {\n this.#users = new Map(list.map((user) => [user.uid, user.name]));\n this.schedule();\n },\n () => undefined\n );\n this.#poll();\n this.refresh();\n }\n\n stop(): void {\n this.stopped = true;\n for (const off of this.#off) off();\n for (const handle of this.#handles) this.#settings.timers.clear(handle);\n this.#handles.clear();\n void this.#watch?.stop();\n }\n\n refresh(): void {\n void this.#readUsage();\n void this.#options.harness.inspect(this.#settings.context).then(\n (inspection) => {\n this.#paused = inspection.scheduling === 'paused';\n this.schedule();\n },\n () => undefined\n );\n this.schedule();\n }\n\n schedule(): void {\n if (this.stopped || this.#build !== undefined) return;\n const wait = Math.max(0, this.#lastBuild + this.#settings.throttleMs - this.#settings.now());\n this.#build = this.#later(() => {\n this.#build = undefined;\n this.#emit();\n }, wait);\n }\n\n #later(task: () => void, ms: number): unknown {\n if (this.stopped) return undefined;\n const handle = this.#settings.timers.set(() => {\n this.#handles.delete(handle);\n if (!this.stopped) task();\n }, ms);\n this.#handles.add(handle);\n return handle;\n }\n\n #watching(watch: TaskGraphWatch): void {\n if (this.stopped) {\n void watch.stop();\n return;\n }\n this.#watch = watch;\n this.#graph = watch.value;\n this.schedule();\n watch.start(async (graph) => {\n this.#graph = graph;\n this.schedule();\n });\n }\n\n #readUsage(): Promise<void> {\n return this.#options.harness.usage(this.#settings.context).then(\n (usage) => {\n this.#usage = usage;\n this.schedule();\n },\n () => undefined\n );\n }\n\n #poll(): void {\n const kernel = this.#options.kernel;\n if (!kernel?.ps) return;\n let settled = false;\n const settle = (entries: readonly PsEntry[] | null) => {\n if (settled || this.stopped) return;\n settled = true;\n this.#settings.timers.clear(timeout);\n this.#handles.delete(timeout);\n this.#processes = entries;\n if (entries) this.#cpu = cpuShares(entries, this.#cpu.marks, this.#settings.now());\n this.#kernel = entries ? 'ok' : 'unreachable';\n this.schedule();\n this.#later(() => this.#poll(), this.#settings.psMs);\n };\n const timeout = this.#later(() => settle(null), this.#settings.psTimeoutMs);\n kernel.ps().then(settle, () => settle(null));\n }\n\n #problem(entry: MonitorProblem): void {\n if (this.#problems.some((known) => known.id === entry.id)) return;\n this.#problems.unshift(entry);\n this.#problems.length = Math.min(this.#problems.length, PROBLEMS_MAX);\n }\n\n #commit(publication: CommitPublication): void {\n let changed = false;\n for (const change of publication.changes) {\n if (change.type === 'task') changed = this.#failed(change.value) || changed;\n else if (change.type === 'document' && change.record.kind === 'pi.usage')\n this.#usageChanged();\n }\n if (changed) this.schedule();\n }\n\n #failed(task: TaskRecord<JsonValue, JsonValue, JsonValue>): boolean {\n if (task.state.status !== 'terminal') return false;\n const outcome = task.state.outcome;\n if (outcome.status !== 'faulted' && outcome.status !== 'orphaned') return false;\n this.#problem({\n id: `task:${task.id}`,\n at: this.#settings.now(),\n agentId: conversations(this.#options.agents.state()).get(task.conversationId) ?? null,\n kind: 'task',\n message: redacted(outcome.status === 'faulted' ? outcome.error.message : outcome.reason),\n });\n return true;\n }\n\n #usageChanged(): void {\n if (this.#usageTimer !== undefined) return;\n this.#usageTimer = this.#later(() => {\n this.#usageTimer = undefined;\n void this.#readUsage();\n }, this.#settings.usageMs);\n }\n\n #since(key: string): number {\n const at = this.#seen.get(key) ?? this.#settings.now();\n this.#next.set(key, at);\n return at;\n }\n\n #agent(agent: Agent, view: ConversationView | undefined, tools: Map<string, string>) {\n const liveDoc = view?.docs['pi.live'] as Live | undefined;\n for (const slot of liveDoc?.tools ?? [])\n if (slot.taskId !== undefined) tools.set(String(slot.taskId), slot.name);\n const inbox = view?.docs['pi.inbox'] as { items?: unknown[] } | undefined;\n const doc = view?.docs['pi.agent'] as\n | { model?: { provider: string; modelId: string } }\n | undefined;\n const generation = liveDoc?.generation;\n const retry = generation?.retry\n ? {\n attempt: generation.attempt,\n since: this.#since(`retry:${agent.id}`),\n error: redacted(generation.retry.error),\n }\n : null;\n if (retry)\n this.#problem({\n id: `retry:${agent.id}:${retry.since}`,\n at: retry.since,\n agentId: agent.id,\n kind: 'retry',\n message: retry.error,\n });\n const last = lastAssistant(view);\n const failed =\n last?.message.stopReason === 'error' ? redacted(last.message.errorMessage || 'error') : null;\n if (failed && last)\n this.#problem({\n id: `turn:${last.id}`,\n at: this.#settings.now(),\n agentId: agent.id,\n kind: 'turn',\n message: failed,\n });\n return {\n id: agent.id,\n name: agent.name,\n kind: agent.kind,\n parentId: agent.parentId,\n model: doc?.model ? `${doc.model.provider}/${doc.model.modelId}` : null,\n running: Boolean(liveDoc?.run),\n queued: inbox?.items?.length ?? 0,\n tool: liveDoc?.tools?.find((slot) => slot.status === 'running')?.name ?? null,\n retry,\n failed,\n context: contextTokens(view),\n };\n }\n\n #task(node: TaskGraphNode, owners: Map<number, string>, details: Map<string, string>) {\n const id = String(node.id);\n const status = node.state.status;\n return {\n id,\n kind: node.kind,\n detail: details.get(id) ?? null,\n agentId: owners.get(node.conversationId) ?? null,\n owner: node.owner === undefined ? null : String(node.owner),\n status,\n phase: phaseOf(node),\n background: node.background,\n aborting: node.abortRequested ? this.#since(`abort:${id}`) : null,\n since: this.#since(`task:${id}:${status}`),\n waits: node.state.status === 'waiting' ? node.state.on.length : 0,\n };\n }\n\n #process(entry: PsEntry, groups: Map<number, string>, programs: Map<number, string>) {\n const argv = entry.argv ?? [];\n const pgid = entry.pgid ?? entry.pid;\n const zombie = entry.state === 'Z';\n programs.set(entry.pid, program(argv));\n const uid = entry.uid;\n return {\n pid: entry.pid,\n ppid: entry.ppid ?? 0,\n pgid,\n user:\n uid === undefined ? null : (this.#users.get(uid) ?? (uid === 0 ? 'root' : `uid ${uid}`)),\n agentId: groups.get(pgid) ?? null,\n command: commandLine(argv),\n state: zombie ? ('Z' as const) : ('S' as const),\n started: entry.started ?? 0,\n zombie: zombie ? this.#since(`zombie:${entry.pid}`) : null,\n tty: Boolean(entry.tty),\n rss: typeof entry.rss === 'number' ? entry.rss : null,\n ...(timed(entry)\n ? { utime: entry.utime, stime: entry.stime, cpu: this.#cpu.shares.get(entry.pid) ?? null }\n : {}),\n };\n }\n\n #emit(): void {\n this.#lastBuild = this.#settings.now();\n this.#next = new Map();\n const registry = this.#options.agents.state();\n const views = this.#options.views.value ?? {};\n const agents = liveAgents(registry);\n const details = new Map<string, string>();\n const rows: MonitorAgent[] = agents.map((agent) =>\n this.#agent(agent, views[agent.id], details)\n );\n for (const scoop of Object.values(registry.scoops))\n details.set(String(scoop.anchor), scoop.name);\n const owners = conversations(registry);\n const tasks: MonitorTask[] = Object.values(this.#graph.tasks).map((node) =>\n this.#task(node, owners, details)\n );\n const groups = new Map<number, string>();\n for (const agent of agents)\n for (const pgid of this.#options.groups?.owned(agent.conversation) ?? [])\n groups.set(pgid, agent.id);\n const programs = new Map<number, string>();\n const entries = this.#processes;\n const processes: MonitorProcess[] | null =\n entries?.map((entry) => this.#process(entry, groups, programs)) ?? null;\n if (entries?.some(timed))\n for (const row of rows) row.cpu = agentCpu(processes as MonitorProcess[], row.id);\n this.#seen = this.#next;\n const feed: MonitorFeed = {\n open: true,\n at: this.#lastBuild,\n usage: this.#usage ? totals(this.#usage) : null,\n agents: rows,\n tasks,\n processes,\n kernel: this.#kernel,\n problems: [...this.#problems],\n paused: this.#paused,\n };\n const key = JSON.stringify({ ...feed, at: 0 });\n if (key === this.#last) return;\n this.#last = key;\n this.#publish(feed, narrowed(feed, programs));\n }\n}\n\nexport function createMonitor(options: MonitorOptions): Monitor {\n const settings: Settings = {\n now: options.now ?? Date.now,\n timers: options.timers ?? globalTimers,\n context: options.context ?? BACKGROUND_CONTEXT,\n psMs: options.psMs ?? PS_MS,\n psTimeoutMs: options.psTimeoutMs ?? PS_TIMEOUT_MS,\n throttleMs: options.throttleMs ?? THROTTLE_MS,\n usageMs: options.usageMs ?? USAGE_MS,\n };\n const { now, timers, context } = settings;\n const ttlMs = options.ttlMs ?? TTL_MS;\n const state = replicatedState<MonitorFeed>(emptyFeed());\n const viewState = replicatedState<MonitorFeed>(emptyFeed());\n const leases = new Map<string, number>();\n let session: Session | undefined;\n let sweep: unknown;\n const publish = (feed: MonitorFeed, view: MonitorFeed) => {\n state.replace(context, feed);\n viewState.replace(context, view);\n };\n const stop = () => {\n if (sweep !== undefined) timers.clear(sweep);\n sweep = undefined;\n const current = session;\n if (!current) return;\n session = undefined;\n current.stop();\n publish(\n { ...(state.value as MonitorFeed), open: false },\n { ...(viewState.value as MonitorFeed), open: false }\n );\n };\n const arm = () => {\n if (sweep !== undefined) timers.clear(sweep);\n sweep = timers.set(expire, Math.max(0, Math.min(...leases.values()) - now()));\n };\n const expire = () => {\n sweep = undefined;\n const at = now();\n for (const [lease, until] of [...leases]) if (until <= at) leases.delete(lease);\n if (leases.size) arm();\n else stop();\n };\n return {\n state,\n viewState,\n async open(lease, resync) {\n const id = lease ?? crypto.randomUUID();\n leases.set(id, now() + ttlMs);\n arm();\n if (!session) {\n session = new Session(options, settings, publish);\n session.start();\n } else if (resync) session.refresh();\n return { lease: id, ttlMs };\n },\n async close(lease) {\n if (!leases.delete(lease)) return;\n if (leases.size) arm();\n else stop();\n },\n active: () => session !== undefined,\n async dispose() {\n leases.clear();\n stop();\n },\n };\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/monitor/redact.js
CHANGED
|
@@ -1,15 +1,14 @@
|
|
|
1
|
-
import { scrub } from "../mcp/credentials.js";
|
|
2
1
|
import { redactSecrets } from "../memory/format.js";
|
|
3
2
|
const TEXT_MAX = 160;
|
|
4
3
|
function cut(text, max = TEXT_MAX) {
|
|
5
4
|
return text.length > max ? `${text.slice(0, max - 1)}\u2026` : text;
|
|
6
5
|
}
|
|
7
|
-
function redacted(text
|
|
8
|
-
return cut(redactSecrets(
|
|
6
|
+
function redacted(text) {
|
|
7
|
+
return cut(redactSecrets(text).text.replace(/\s+/g, " ").trim());
|
|
9
8
|
}
|
|
10
9
|
const EXPORTS = /^export (?:[A-Z_][A-Z0-9_]*='(?:[^']|'\\'')*' ?)+; /;
|
|
11
|
-
function commandLine(argv
|
|
12
|
-
return redacted(argv.map((arg) => arg.replace(EXPORTS, "")).join(" ")
|
|
10
|
+
function commandLine(argv) {
|
|
11
|
+
return redacted(argv.map((arg) => arg.replace(EXPORTS, "")).join(" "));
|
|
13
12
|
}
|
|
14
13
|
function program(argv) {
|
|
15
14
|
const first = argv[0] ?? "";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/monitor/redact.ts"],
|
|
4
|
-
"sourcesContent": ["import {
|
|
5
|
-
"mappings": "AAAA,SAAS,
|
|
4
|
+
"sourcesContent": ["import { redactSecrets } from '../memory/format.ts';\n\nexport const TEXT_MAX = 160;\n\nexport function cut(text: string, max = TEXT_MAX): string {\n return text.length > max ? `${text.slice(0, max - 1)}\u2026` : text;\n}\n\nexport function redacted(text: string): string {\n return cut(redactSecrets(text).text.replace(/\\s+/g, ' ').trim());\n}\n\nconst EXPORTS = /^export (?:[A-Z_][A-Z0-9_]*='(?:[^']|'\\\\'')*' ?)+; /;\n\nexport function commandLine(argv: readonly string[]): string {\n return redacted(argv.map((arg) => arg.replace(EXPORTS, '')).join(' '));\n}\n\nexport function program(argv: readonly string[]): string {\n const first = argv[0] ?? '';\n return cut(first.split('/').pop() || first);\n}\n"],
|
|
5
|
+
"mappings": "AAAA,SAAS,qBAAqB;AAEvB,MAAM,WAAW;AAEjB,SAAS,IAAI,MAAc,MAAM,UAAkB;AACxD,SAAO,KAAK,SAAS,MAAM,GAAG,KAAK,MAAM,GAAG,MAAM,CAAC,CAAC,WAAM;AAC5D;AAEO,SAAS,SAAS,MAAsB;AAC7C,SAAO,IAAI,cAAc,IAAI,EAAE,KAAK,QAAQ,QAAQ,GAAG,EAAE,KAAK,CAAC;AACjE;AAEA,MAAM,UAAU;AAET,SAAS,YAAY,MAAiC;AAC3D,SAAO,SAAS,KAAK,IAAI,CAAC,QAAQ,IAAI,QAAQ,SAAS,EAAE,CAAC,EAAE,KAAK,GAAG,CAAC;AACvE;AAEO,SAAS,QAAQ,MAAiC;AACvD,QAAM,QAAQ,KAAK,CAAC,KAAK;AACzB,SAAO,IAAI,MAAM,MAAM,GAAG,EAAE,IAAI,KAAK,KAAK;AAC5C;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
const KEYS_IN_VAULT = "model keys are kept in seven's vault: enter them in Settings \u203A Accounts";
|
|
2
|
+
function vaultCredentials(records, env = () => void 0) {
|
|
3
|
+
return {
|
|
4
|
+
async read(providerId) {
|
|
5
|
+
const record = records.model(providerId);
|
|
6
|
+
if (!record) return void 0;
|
|
7
|
+
const extra = env(providerId);
|
|
8
|
+
return {
|
|
9
|
+
type: "api_key",
|
|
10
|
+
key: record.placeholder,
|
|
11
|
+
...extra && Object.keys(extra).length ? { env: { ...extra } } : {}
|
|
12
|
+
};
|
|
13
|
+
},
|
|
14
|
+
async list() {
|
|
15
|
+
const providers = records.state.value.filter((record) => record.kind === "model" && record.provider !== void 0).map((record) => record.provider);
|
|
16
|
+
return [...new Set(providers)].map(
|
|
17
|
+
(providerId) => ({ providerId, type: "api_key" })
|
|
18
|
+
);
|
|
19
|
+
},
|
|
20
|
+
async modify() {
|
|
21
|
+
throw new Error(KEYS_IN_VAULT);
|
|
22
|
+
},
|
|
23
|
+
async delete() {
|
|
24
|
+
throw new Error(KEYS_IN_VAULT);
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
export {
|
|
29
|
+
KEYS_IN_VAULT,
|
|
30
|
+
vaultCredentials
|
|
31
|
+
};
|
|
32
|
+
//# sourceMappingURL=credentials.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/secrets/credentials.ts"],
|
|
4
|
+
"sourcesContent": ["import type { Credential, CredentialInfo, CredentialStore } from '@earendil-works/pi-ai';\nimport type { VaultRecords } from './records.ts';\n\nexport const KEYS_IN_VAULT =\n \"model keys are kept in seven's vault: enter them in Settings \u203A Accounts\";\n\nexport type FieldsOf = (providerId: string) => Readonly<Record<string, string>> | undefined;\n\nexport function vaultCredentials(\n records: Pick<VaultRecords, 'model' | 'state'>,\n env: FieldsOf = () => undefined\n): CredentialStore {\n return {\n async read(providerId) {\n const record = records.model(providerId);\n if (!record) return undefined;\n const extra = env(providerId);\n return {\n type: 'api_key',\n key: record.placeholder,\n ...(extra && Object.keys(extra).length ? { env: { ...extra } } : {}),\n } satisfies Credential;\n },\n async list() {\n const providers = records.state.value\n .filter((record) => record.kind === 'model' && record.provider !== undefined)\n .map((record) => record.provider as string);\n return [...new Set(providers)].map(\n (providerId): CredentialInfo => ({ providerId, type: 'api_key' })\n );\n },\n async modify() {\n throw new Error(KEYS_IN_VAULT);\n },\n async delete() {\n throw new Error(KEYS_IN_VAULT);\n },\n };\n}\n"],
|
|
5
|
+
"mappings": "AAGO,MAAM,gBACX;AAIK,SAAS,iBACd,SACA,MAAgB,MAAM,QACL;AACjB,SAAO;AAAA,IACL,MAAM,KAAK,YAAY;AACrB,YAAM,SAAS,QAAQ,MAAM,UAAU;AACvC,UAAI,CAAC,OAAQ,QAAO;AACpB,YAAM,QAAQ,IAAI,UAAU;AAC5B,aAAO;AAAA,QACL,MAAM;AAAA,QACN,KAAK,OAAO;AAAA,QACZ,GAAI,SAAS,OAAO,KAAK,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,GAAG,MAAM,EAAE,IAAI,CAAC;AAAA,MACpE;AAAA,IACF;AAAA,IACA,MAAM,OAAO;AACX,YAAM,YAAY,QAAQ,MAAM,MAC7B,OAAO,CAAC,WAAW,OAAO,SAAS,WAAW,OAAO,aAAa,MAAS,EAC3E,IAAI,CAAC,WAAW,OAAO,QAAkB;AAC5C,aAAO,CAAC,GAAG,IAAI,IAAI,SAAS,CAAC,EAAE;AAAA,QAC7B,CAAC,gBAAgC,EAAE,YAAY,MAAM,UAAU;AAAA,MACjE;AAAA,IACF;AAAA,IACA,MAAM,SAAS;AACb,YAAM,IAAI,MAAM,aAAa;AAAA,IAC/B;AAAA,IACA,MAAM,SAAS;AACb,YAAM,IAAI,MAAM,aAAa;AAAA,IAC/B;AAAA,EACF;AACF;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|