@ai-ecoverse/slicc-agent 6.19.15 → 7.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.
Files changed (78) hide show
  1. package/README.md +17 -33
  2. package/dist/agent.js +10 -1
  3. package/dist/agent.js.map +2 -2
  4. package/dist/agents.js +2 -0
  5. package/dist/agents.js.map +2 -2
  6. package/dist/approvals/policy.js +2 -0
  7. package/dist/approvals/policy.js.map +2 -2
  8. package/dist/approvals/record.js +2 -0
  9. package/dist/approvals/record.js.map +2 -2
  10. package/dist/checkpoints.js +5 -0
  11. package/dist/checkpoints.js.map +7 -0
  12. package/dist/codemode/index.js +2 -0
  13. package/dist/codemode/index.js.map +2 -2
  14. package/dist/cone.js +2 -0
  15. package/dist/cone.js.map +2 -2
  16. package/dist/guests/guard.js +3 -0
  17. package/dist/guests/guard.js.map +2 -2
  18. package/dist/guests/review.js +4 -1
  19. package/dist/guests/review.js.map +2 -2
  20. package/dist/guests/scoop.js +3 -0
  21. package/dist/guests/scoop.js.map +2 -2
  22. package/dist/guests/seats.js +2 -0
  23. package/dist/guests/seats.js.map +2 -2
  24. package/dist/guests/tags.js +2 -0
  25. package/dist/guests/tags.js.map +2 -2
  26. package/dist/licks/boot.js +2 -0
  27. package/dist/licks/boot.js.map +2 -2
  28. package/dist/licks/licks.js +2 -0
  29. package/dist/licks/licks.js.map +2 -2
  30. package/dist/mcp/allow.js +2 -0
  31. package/dist/mcp/allow.js.map +2 -2
  32. package/dist/memory/extract.js +2 -0
  33. package/dist/memory/extract.js.map +2 -2
  34. package/dist/monitor/index.js +3 -1
  35. package/dist/monitor/index.js.map +2 -2
  36. package/dist/pause.js +26 -0
  37. package/dist/pause.js.map +7 -0
  38. package/dist/preferred.js +6 -6
  39. package/dist/preferred.js.map +1 -1
  40. package/dist/providers.js +1 -1
  41. package/dist/providers.js.map +1 -1
  42. package/dist/scoops/extension.js +2 -1
  43. package/dist/scoops/extension.js.map +2 -2
  44. package/dist/scoops/service.js +2 -0
  45. package/dist/scoops/service.js.map +2 -2
  46. package/dist/secrets/legacy.js +2 -0
  47. package/dist/secrets/legacy.js.map +2 -2
  48. package/dist/selection.js +2 -0
  49. package/dist/selection.js.map +2 -2
  50. package/dist/services.js.map +2 -2
  51. package/dist/settings.js +33 -5
  52. package/dist/settings.js.map +3 -3
  53. package/dist/spectrum/budget.js +30 -0
  54. package/dist/spectrum/budget.js.map +7 -0
  55. package/dist/spectrum/index.js +7 -5
  56. package/dist/spectrum/index.js.map +2 -2
  57. package/dist/spectrum/monitor-port.js +24 -4
  58. package/dist/spectrum/monitor-port.js.map +2 -2
  59. package/dist/spectrum/tray-port.js +19 -3
  60. package/dist/spectrum/tray-port.js.map +2 -2
  61. package/dist/sprinkles/sprinkles.js +2 -0
  62. package/dist/sprinkles/sprinkles.js.map +2 -2
  63. package/dist/supergrok.js +73 -0
  64. package/dist/supergrok.js.map +7 -0
  65. package/dist/titles/labels.js +2 -0
  66. package/dist/titles/labels.js.map +2 -2
  67. package/dist/types/agent.d.ts +4 -0
  68. package/dist/types/checkpoints.d.ts +1 -0
  69. package/dist/types/pause.d.ts +6 -0
  70. package/dist/types/services.d.ts +5 -2
  71. package/dist/types/settings.d.ts +8 -1
  72. package/dist/types/spectrum/budget.d.ts +16 -0
  73. package/dist/types/spectrum/monitor-port.d.ts +2 -0
  74. package/dist/types/spectrum/tray-port.d.ts +2 -1
  75. package/dist/types/supergrok.d.ts +12 -0
  76. package/dist/workflow/run.js +5 -0
  77. package/dist/workflow/run.js.map +2 -2
  78. package/package.json +11 -11
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/pause.ts"],
4
+ "sourcesContent": ["import type { Context } from '@earendil-works/chord';\n\nexport interface PhaseClock {\n now(): number;\n setTimer(callback: () => void, delayMs: number): () => void;\n}\n\nfunction tick(clock: PhaseClock, delayMs: number, signal: AbortSignal | undefined) {\n return new Promise<void>((resolve, reject) => {\n const abort = () => {\n disarm();\n reject(signal?.reason);\n };\n const disarm = clock.setTimer(() => {\n signal?.removeEventListener('abort', abort);\n resolve();\n }, delayMs);\n signal?.addEventListener('abort', abort, { once: true });\n });\n}\n\nexport async function pauseUntil(clock: PhaseClock, until: number, context: Context) {\n const signal = context.abortSignal;\n for (;;) {\n signal?.throwIfAborted();\n const remaining = until - clock.now();\n if (remaining <= 0) return;\n await tick(clock, remaining, signal);\n }\n}\n"],
5
+ "mappings": "AAOA,SAAS,KAAK,OAAmB,SAAiB,QAAiC;AACjF,SAAO,IAAI,QAAc,CAAC,SAAS,WAAW;AAC5C,UAAM,QAAQ,MAAM;AAClB,aAAO;AACP,aAAO,QAAQ,MAAM;AAAA,IACvB;AACA,UAAM,SAAS,MAAM,SAAS,MAAM;AAClC,cAAQ,oBAAoB,SAAS,KAAK;AAC1C,cAAQ;AAAA,IACV,GAAG,OAAO;AACV,YAAQ,iBAAiB,SAAS,OAAO,EAAE,MAAM,KAAK,CAAC;AAAA,EACzD,CAAC;AACH;AAEA,eAAsB,WAAW,OAAmB,OAAe,SAAkB;AACnF,QAAM,SAAS,QAAQ;AACvB,aAAS;AACP,YAAQ,eAAe;AACvB,UAAM,YAAY,QAAQ,MAAM,IAAI;AACpC,QAAI,aAAa,EAAG;AACpB,UAAM,KAAK,OAAO,WAAW,MAAM;AAAA,EACrC;AACF;",
6
+ "names": []
7
+ }
package/dist/preferred.js CHANGED
@@ -5,7 +5,7 @@ const PREFERRED_MODELS = {
5
5
  anthropic: "claude-opus-4-8",
6
6
  openai: "gpt-5.5",
7
7
  azure: "gpt-5.4",
8
- nvidia: "nvidia/nemotron-3-ultra-550b-a55b",
8
+ nvidia: "nvidia/nemotron-3.5-super-vl-120b-a12b",
9
9
  deepseek: "deepseek-v4-pro",
10
10
  google: "gemini-3.1-pro-preview",
11
11
  "google-vertex": "gemini-3.1-pro-preview",
@@ -28,17 +28,17 @@ const PREFERRED_MODELS = {
28
28
  opencode: "kimi-k2.6",
29
29
  "opencode-go": "kimi-k3",
30
30
  "kimi-coding": "kimi-for-coding",
31
- "openai-codex": "gpt-5.5",
31
+ "openai-codex": "gpt-6.1-sol",
32
32
  meta: "muse-spark-1.3",
33
33
  "cloudflare-workers-ai": "@cf/moonshotai/kimi-k2.6",
34
34
  "cloudflare-ai-gateway": "workers-ai/@cf/moonshotai/kimi-k2.6",
35
35
  "qwen-token-plan": "qwen3.7-max",
36
36
  "qwen-token-plan-cn": "qwen3.7-max",
37
37
  "qwen-token-plan-individual": "qwen3.8-max",
38
- xiaomi: "mimo-v2.5-pro",
39
- "xiaomi-token-plan-cn": "mimo-v2.5-pro",
40
- "xiaomi-token-plan-ams": "mimo-v2.5-pro",
41
- "xiaomi-token-plan-sgp": "mimo-v2.5-pro"
38
+ xiaomi: "mimo-v2.6-pro",
39
+ "xiaomi-token-plan-cn": "mimo-v2.6-pro",
40
+ "xiaomi-token-plan-ams": "mimo-v2.6-pro",
41
+ "xiaomi-token-plan-sgp": "mimo-v2.6-pro"
42
42
  };
43
43
  function preferredModel(providerId, available) {
44
44
  const preferredId = PREFERRED_MODELS[providerId];
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/preferred.ts"],
4
- "sourcesContent": ["export const BEDROCK = 'amazon-bedrock';\n\nexport const PREFERRED_MODELS: Readonly<Record<string, string>> = {\n [BEDROCK]: 'us.anthropic.claude-sonnet-5-5',\n 'ant-ling': 'Ring-2.6-1T',\n anthropic: 'claude-opus-4-8',\n openai: 'gpt-5.5',\n azure: 'gpt-5.4',\n nvidia: 'nvidia/nemotron-3-ultra-550b-a55b',\n deepseek: 'deepseek-v4-pro',\n google: 'gemini-3.1-pro-preview',\n 'google-vertex': 'gemini-3.1-pro-preview',\n openrouter: 'moonshotai/kimi-k2.6',\n 'vercel-ai-gateway': 'zai/glm-5.1',\n xai: 'grok-4.7',\n groq: 'openai/gpt-oss-120b',\n cerebras: 'gpt-oss-120b',\n zai: 'glm-5.3',\n 'zai-coding-cn': 'glm-5.3',\n mistral: 'devstral-medium-latest',\n minimax: 'MiniMax-M2.7',\n 'minimax-cn': 'MiniMax-M2.7',\n moonshotai: 'kimi-k2.6',\n 'moonshotai-cn': 'kimi-k2.6',\n huggingface: 'moonshotai/Kimi-K2.6',\n fireworks: 'accounts/fireworks/models/kimi-k3',\n together: 'moonshotai/Kimi-K3',\n baseten: 'zai-org/GLM-5.2',\n opencode: 'kimi-k2.6',\n 'opencode-go': 'kimi-k3',\n 'kimi-coding': 'kimi-for-coding',\n 'openai-codex': 'gpt-5.5',\n meta: 'muse-spark-1.3',\n 'cloudflare-workers-ai': '@cf/moonshotai/kimi-k2.6',\n 'cloudflare-ai-gateway': 'workers-ai/@cf/moonshotai/kimi-k2.6',\n 'qwen-token-plan': 'qwen3.7-max',\n 'qwen-token-plan-cn': 'qwen3.7-max',\n 'qwen-token-plan-individual': 'qwen3.8-max',\n xiaomi: 'mimo-v2.5-pro',\n 'xiaomi-token-plan-cn': 'mimo-v2.5-pro',\n 'xiaomi-token-plan-ams': 'mimo-v2.5-pro',\n 'xiaomi-token-plan-sgp': 'mimo-v2.5-pro',\n};\n\nexport function preferredModel<T extends { id: string }>(\n providerId: string,\n available: readonly T[]\n): T | undefined {\n const preferredId = PREFERRED_MODELS[providerId];\n return available.find((model) => model.id === preferredId) ?? available[0];\n}\n"],
4
+ "sourcesContent": ["export const BEDROCK = 'amazon-bedrock';\n\nexport const PREFERRED_MODELS: Readonly<Record<string, string>> = {\n [BEDROCK]: 'us.anthropic.claude-sonnet-5-5',\n 'ant-ling': 'Ring-2.6-1T',\n anthropic: 'claude-opus-4-8',\n openai: 'gpt-5.5',\n azure: 'gpt-5.4',\n nvidia: 'nvidia/nemotron-3.5-super-vl-120b-a12b',\n deepseek: 'deepseek-v4-pro',\n google: 'gemini-3.1-pro-preview',\n 'google-vertex': 'gemini-3.1-pro-preview',\n openrouter: 'moonshotai/kimi-k2.6',\n 'vercel-ai-gateway': 'zai/glm-5.1',\n xai: 'grok-4.7',\n groq: 'openai/gpt-oss-120b',\n cerebras: 'gpt-oss-120b',\n zai: 'glm-5.3',\n 'zai-coding-cn': 'glm-5.3',\n mistral: 'devstral-medium-latest',\n minimax: 'MiniMax-M2.7',\n 'minimax-cn': 'MiniMax-M2.7',\n moonshotai: 'kimi-k2.6',\n 'moonshotai-cn': 'kimi-k2.6',\n huggingface: 'moonshotai/Kimi-K2.6',\n fireworks: 'accounts/fireworks/models/kimi-k3',\n together: 'moonshotai/Kimi-K3',\n baseten: 'zai-org/GLM-5.2',\n opencode: 'kimi-k2.6',\n 'opencode-go': 'kimi-k3',\n 'kimi-coding': 'kimi-for-coding',\n 'openai-codex': 'gpt-6.1-sol',\n meta: 'muse-spark-1.3',\n 'cloudflare-workers-ai': '@cf/moonshotai/kimi-k2.6',\n 'cloudflare-ai-gateway': 'workers-ai/@cf/moonshotai/kimi-k2.6',\n 'qwen-token-plan': 'qwen3.7-max',\n 'qwen-token-plan-cn': 'qwen3.7-max',\n 'qwen-token-plan-individual': 'qwen3.8-max',\n xiaomi: 'mimo-v2.6-pro',\n 'xiaomi-token-plan-cn': 'mimo-v2.6-pro',\n 'xiaomi-token-plan-ams': 'mimo-v2.6-pro',\n 'xiaomi-token-plan-sgp': 'mimo-v2.6-pro',\n};\n\nexport function preferredModel<T extends { id: string }>(\n providerId: string,\n available: readonly T[]\n): T | undefined {\n const preferredId = PREFERRED_MODELS[providerId];\n return available.find((model) => model.id === preferredId) ?? available[0];\n}\n"],
5
5
  "mappings": "AAAO,MAAM,UAAU;AAEhB,MAAM,mBAAqD;AAAA,EAChE,CAAC,OAAO,GAAG;AAAA,EACX,YAAY;AAAA,EACZ,WAAW;AAAA,EACX,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,UAAU;AAAA,EACV,QAAQ;AAAA,EACR,iBAAiB;AAAA,EACjB,YAAY;AAAA,EACZ,qBAAqB;AAAA,EACrB,KAAK;AAAA,EACL,MAAM;AAAA,EACN,UAAU;AAAA,EACV,KAAK;AAAA,EACL,iBAAiB;AAAA,EACjB,SAAS;AAAA,EACT,SAAS;AAAA,EACT,cAAc;AAAA,EACd,YAAY;AAAA,EACZ,iBAAiB;AAAA,EACjB,aAAa;AAAA,EACb,WAAW;AAAA,EACX,UAAU;AAAA,EACV,SAAS;AAAA,EACT,UAAU;AAAA,EACV,eAAe;AAAA,EACf,eAAe;AAAA,EACf,gBAAgB;AAAA,EAChB,MAAM;AAAA,EACN,yBAAyB;AAAA,EACzB,yBAAyB;AAAA,EACzB,mBAAmB;AAAA,EACnB,sBAAsB;AAAA,EACtB,8BAA8B;AAAA,EAC9B,QAAQ;AAAA,EACR,wBAAwB;AAAA,EACxB,yBAAyB;AAAA,EACzB,yBAAyB;AAC3B;AAEO,SAAS,eACd,YACA,WACe;AACf,QAAM,cAAc,iBAAiB,UAAU;AAC/C,SAAO,UAAU,KAAK,CAAC,UAAU,MAAM,OAAO,WAAW,KAAK,UAAU,CAAC;AAC3E;",
6
6
  "names": []
7
7
  }
package/dist/providers.js CHANGED
@@ -355,7 +355,7 @@ const KEY_PROVIDERS = [
355
355
  env: "ZAI_CODING_CN_API_KEY",
356
356
  description: "GLM models on Zhipu\u2019s coding plan in China.",
357
357
  keyUrl: "https://open.bigmodel.cn/usercenter/apikeys",
358
- cors: true
358
+ cors: false
359
359
  },
360
360
  {
361
361
  id: "nvidia",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/providers.ts"],
4
- "sourcesContent": ["import type { Provider } from '@earendil-works/pi-ai';\nimport { antLingProvider } from '@earendil-works/pi-ai/providers/ant-ling';\nimport { anthropicProvider } from '@earendil-works/pi-ai/providers/anthropic';\nimport { azureProvider } from '@earendil-works/pi-ai/providers/azure';\nimport { basetenProvider } from '@earendil-works/pi-ai/providers/baseten';\nimport { cerebrasProvider } from '@earendil-works/pi-ai/providers/cerebras';\nimport { cloudflareAIGatewayProvider } from '@earendil-works/pi-ai/providers/cloudflare-ai-gateway';\nimport { cloudflareWorkersAIProvider } from '@earendil-works/pi-ai/providers/cloudflare-workers-ai';\nimport { deepseekProvider } from '@earendil-works/pi-ai/providers/deepseek';\nimport { fireworksProvider } from '@earendil-works/pi-ai/providers/fireworks';\nimport { groqProvider } from '@earendil-works/pi-ai/providers/groq';\nimport { huggingfaceProvider } from '@earendil-works/pi-ai/providers/huggingface';\nimport { kimiCodingProvider } from '@earendil-works/pi-ai/providers/kimi-coding';\nimport { metaProvider } from '@earendil-works/pi-ai/providers/meta';\nimport { minimaxProvider } from '@earendil-works/pi-ai/providers/minimax';\nimport { minimaxCnProvider } from '@earendil-works/pi-ai/providers/minimax-cn';\nimport { mistralProvider } from '@earendil-works/pi-ai/providers/mistral';\nimport { moonshotaiProvider } from '@earendil-works/pi-ai/providers/moonshotai';\nimport { moonshotaiCnProvider } from '@earendil-works/pi-ai/providers/moonshotai-cn';\nimport { nvidiaProvider } from '@earendil-works/pi-ai/providers/nvidia';\nimport { openaiProvider } from '@earendil-works/pi-ai/providers/openai';\nimport { opencodeProvider } from '@earendil-works/pi-ai/providers/opencode';\nimport { opencodeGoProvider } from '@earendil-works/pi-ai/providers/opencode-go';\nimport { openrouterProvider } from '@earendil-works/pi-ai/providers/openrouter';\nimport { qwenTokenPlanProvider } from '@earendil-works/pi-ai/providers/qwen-token-plan';\nimport { qwenTokenPlanCnProvider } from '@earendil-works/pi-ai/providers/qwen-token-plan-cn';\nimport { qwenTokenPlanIndividualProvider } from '@earendil-works/pi-ai/providers/qwen-token-plan-individual';\nimport { togetherProvider } from '@earendil-works/pi-ai/providers/together';\nimport { vercelAIGatewayProvider } from '@earendil-works/pi-ai/providers/vercel-ai-gateway';\nimport { xaiProvider } from '@earendil-works/pi-ai/providers/xai';\nimport { xiaomiProvider } from '@earendil-works/pi-ai/providers/xiaomi';\nimport { xiaomiTokenPlanAmsProvider } from '@earendil-works/pi-ai/providers/xiaomi-token-plan-ams';\nimport { xiaomiTokenPlanCnProvider } from '@earendil-works/pi-ai/providers/xiaomi-token-plan-cn';\nimport { xiaomiTokenPlanSgpProvider } from '@earendil-works/pi-ai/providers/xiaomi-token-plan-sgp';\nimport { zaiProvider } from '@earendil-works/pi-ai/providers/zai';\nimport { zaiCodingCnProvider } from '@earendil-works/pi-ai/providers/zai-coding-cn';\nimport { CODEX } from './sign-ins.ts';\n\nexport interface FieldOption {\n value: string;\n label: string;\n}\n\nexport interface FieldInput {\n name: string;\n label: string;\n required?: boolean;\n placeholder?: string;\n help?: string;\n customBase?: true;\n vaultSetting?: string;\n options?: readonly FieldOption[];\n value?: string;\n}\n\nexport interface FieldSpec extends FieldInput {\n env(value: string): Record<string, string> | string;\n}\n\nexport interface KeyProvider {\n id: string;\n make: () => Provider;\n env: string;\n description: string;\n keyUrl: string;\n cors: boolean;\n signIn?: true;\n fields?: readonly FieldSpec[];\n}\n\nconst RESOURCE = /^[a-z0-9][a-z0-9-]{0,62}$/i;\nconst DEPLOYMENTS = /^[^=,\\s]+\\s*=\\s*[^=,\\s]+(\\s*,\\s*[^=,\\s]+\\s*=\\s*[^=,\\s]+)*$/;\n\nexport function httpsBase(value: string): URL | undefined {\n const url = URL.parse(value);\n if (url?.protocol !== 'https:' || url.username || url.password) return undefined;\n return url.port === '' || url.port === '443' ? url : undefined;\n}\n\nfunction azureEndpoint(value: string): Record<string, string> | string {\n if (RESOURCE.test(value)) return { AZURE_OPENAI_RESOURCE_NAME: value };\n const url = httpsBase(value);\n if (!url)\n return 'Enter your Azure resource name, or its endpoint as an https:// address without a port or a user name.';\n return { AZURE_OPENAI_BASE_URL: url.href.replace(/\\/+$/, '') };\n}\n\nexport const AZURE = 'azure';\n\nexport function azureBase(env: Readonly<Record<string, string>>): string | undefined {\n if (env.AZURE_OPENAI_BASE_URL) return env.AZURE_OPENAI_BASE_URL;\n const name = env.AZURE_OPENAI_RESOURCE_NAME;\n return name ? `https://${name}.openai.azure.com/openai/v1` : undefined;\n}\n\nconst REGION = /^[a-z]{2,}(-[a-z]+)+-\\d{1,2}$/;\nconst ACCOUNT = /^[0-9a-f]{32}$/i;\nconst GATEWAY = /^[A-Za-z0-9_-]{1,64}$/;\n\nconst checked =\n (pattern: RegExp, env: string, problem: string) =>\n (value: string): Record<string, string> | string =>\n pattern.test(value) ? { [env]: value } : problem;\n\nconst BEDROCK_REGIONS: readonly (readonly [string, string])[] = [\n ['ap-northeast-1', 'Asia Pacific (Tokyo)'],\n ['ap-northeast-2', 'Asia Pacific (Seoul)'],\n ['ap-northeast-3', 'Asia Pacific (Osaka)'],\n ['ap-south-1', 'Asia Pacific (Mumbai)'],\n ['ap-south-2', 'Asia Pacific (Hyderabad)'],\n ['ap-southeast-1', 'Asia Pacific (Singapore)'],\n ['ap-southeast-2', 'Asia Pacific (Sydney)'],\n ['ca-central-1', 'Canada (Central)'],\n ['eu-central-1', 'Europe (Frankfurt)'],\n ['eu-central-2', 'Europe (Zurich)'],\n ['eu-north-1', 'Europe (Stockholm)'],\n ['eu-south-1', 'Europe (Milan)'],\n ['eu-south-2', 'Europe (Spain)'],\n ['eu-west-1', 'Europe (Ireland)'],\n ['eu-west-2', 'Europe (London)'],\n ['eu-west-3', 'Europe (Paris)'],\n ['sa-east-1', 'South America (S\u00E3o Paulo)'],\n ['us-east-1', 'US East (N. Virginia)'],\n ['us-gov-east-1', 'AWS GovCloud (US-East)'],\n ['us-gov-west-1', 'AWS GovCloud (US-West)'],\n ['us-west-2', 'US West (Oregon)'],\n];\n\nexport const DEFAULT_REGION = 'us-west-2';\n\nexport const REGION_FIELD: FieldSpec = {\n name: 'region',\n label: 'Region',\n help: 'The AWS region your Bedrock models run in.',\n options: BEDROCK_REGIONS.map(([value, label]) => ({ value, label: `${label}, ${value}` })),\n value: DEFAULT_REGION,\n env: checked(REGION, 'AWS_REGION', 'Enter an AWS region such as us-west-2.'),\n};\n\nconst ACCOUNT_FIELD: FieldSpec = {\n name: 'account',\n label: 'Account ID',\n required: true,\n placeholder: '0123456789abcdef0123456789abcdef',\n help: 'The 32-character ID on your Cloudflare dashboard\u2019s account overview.',\n vaultSetting: 'CLOUDFLARE_ACCOUNT_ID',\n env: checked(\n ACCOUNT,\n 'CLOUDFLARE_ACCOUNT_ID',\n 'A Cloudflare account ID is 32 characters of 0\u20139 and a\u2013f.'\n ),\n};\n\nexport const KEY_PROVIDERS: readonly KeyProvider[] = [\n {\n id: 'azure',\n make: azureProvider,\n env: 'AZURE_OPENAI_API_KEY',\n description: 'OpenAI models deployed in your own Azure OpenAI or AI Foundry resource.',\n keyUrl: 'https://portal.azure.com',\n cors: true,\n fields: [\n {\n name: 'endpoint',\n label: 'Endpoint',\n required: true,\n placeholder: 'my-resource or https://my-resource.openai.azure.com',\n help: 'Your resource\u2019s name, or its endpoint address from Keys and Endpoint.',\n customBase: true,\n vaultSetting: 'AZURE_OPENAI_RESOURCE_NAME',\n env: azureEndpoint,\n },\n {\n name: 'deployments',\n label: 'Deployments',\n placeholder: 'gpt-5.4=my-gpt',\n help: 'Only for deployments named differently from their model, as model=deployment, separated by commas.',\n env: (value) =>\n DEPLOYMENTS.test(value)\n ? { AZURE_OPENAI_DEPLOYMENT_NAME_MAP: value }\n : 'Write each deployment as model=deployment, separated by commas.',\n },\n ],\n },\n {\n id: 'cloudflare-workers-ai',\n make: cloudflareWorkersAIProvider,\n env: 'CLOUDFLARE_API_KEY',\n description: 'Open models on Cloudflare Workers AI, in your Cloudflare account.',\n keyUrl: 'https://dash.cloudflare.com/profile/api-tokens',\n cors: false,\n fields: [ACCOUNT_FIELD],\n },\n {\n id: 'cloudflare-ai-gateway',\n make: cloudflareAIGatewayProvider,\n env: 'CLOUDFLARE_API_KEY',\n description: 'Models from many labs through your Cloudflare AI Gateway.',\n keyUrl: 'https://dash.cloudflare.com/profile/api-tokens',\n cors: false,\n fields: [\n ACCOUNT_FIELD,\n {\n name: 'gateway',\n label: 'Gateway ID',\n required: true,\n placeholder: 'my-gateway',\n help: 'The name of your gateway under AI \u203A AI Gateway.',\n vaultSetting: 'CLOUDFLARE_GATEWAY_ID',\n env: checked(\n GATEWAY,\n 'CLOUDFLARE_GATEWAY_ID',\n 'A gateway ID is letters, digits, - and _, up to 64 characters.'\n ),\n },\n ],\n },\n {\n id: 'anthropic',\n make: anthropicProvider,\n env: 'ANTHROPIC_API_KEY',\n description: 'Claude models, with an API key from the Claude Console.',\n keyUrl: 'https://console.anthropic.com/settings/keys',\n cors: true,\n },\n {\n id: 'openai',\n make: openaiProvider,\n env: 'OPENAI_API_KEY',\n description: 'GPT models, with an API key from the OpenAI platform.',\n keyUrl: 'https://platform.openai.com/api-keys',\n cors: true,\n },\n {\n id: 'mistral',\n make: mistralProvider,\n env: 'MISTRAL_API_KEY',\n description: 'Mistral and Devstral models from La Plateforme.',\n keyUrl: 'https://console.mistral.ai/api-keys',\n cors: true,\n },\n {\n id: 'groq',\n make: groqProvider,\n env: 'GROQ_API_KEY',\n description: 'Open models on Groq\u2019s fast inference.',\n keyUrl: 'https://console.groq.com/keys',\n cors: true,\n },\n {\n id: 'deepseek',\n make: deepseekProvider,\n env: 'DEEPSEEK_API_KEY',\n description: 'DeepSeek\u2019s own models.',\n keyUrl: 'https://platform.deepseek.com/api_keys',\n cors: true,\n },\n {\n id: 'together',\n make: togetherProvider,\n env: 'TOGETHER_API_KEY',\n description: 'Open models hosted by Together AI.',\n keyUrl: 'https://api.together.ai/settings/api-keys',\n cors: true,\n },\n {\n id: 'huggingface',\n make: huggingfaceProvider,\n env: 'HF_TOKEN',\n description: 'Open models through Hugging Face\u2019s inference router.',\n keyUrl: 'https://huggingface.co/settings/tokens',\n cors: true,\n },\n {\n id: 'xiaomi',\n make: xiaomiProvider,\n env: 'XIAOMI_API_KEY',\n description: 'Xiaomi\u2019s MiMo models.',\n keyUrl: 'https://platform.xiaomimimo.com/#/console/api-keys',\n cors: true,\n },\n {\n id: 'xiaomi-token-plan-ams',\n make: xiaomiTokenPlanAmsProvider,\n env: 'XIAOMI_TOKEN_PLAN_AMS_API_KEY',\n description: 'MiMo models on a Xiaomi token plan, served from Amsterdam.',\n keyUrl: 'https://platform.xiaomimimo.com/#/console/api-keys',\n cors: true,\n },\n {\n id: 'xiaomi-token-plan-cn',\n make: xiaomiTokenPlanCnProvider,\n env: 'XIAOMI_TOKEN_PLAN_CN_API_KEY',\n description: 'MiMo models on a Xiaomi token plan, served from China.',\n keyUrl: 'https://platform.xiaomimimo.com/#/console/api-keys',\n cors: true,\n },\n {\n id: 'xiaomi-token-plan-sgp',\n make: xiaomiTokenPlanSgpProvider,\n env: 'XIAOMI_TOKEN_PLAN_SGP_API_KEY',\n description: 'MiMo models on a Xiaomi token plan, served from Singapore.',\n keyUrl: 'https://platform.xiaomimimo.com/#/console/api-keys',\n cors: true,\n },\n {\n id: 'cerebras',\n make: cerebrasProvider,\n env: 'CEREBRAS_API_KEY',\n description: 'Open models on Cerebras inference.',\n keyUrl: 'https://cloud.cerebras.ai',\n cors: false,\n },\n {\n id: 'openrouter',\n make: openrouterProvider,\n env: 'OPENROUTER_API_KEY',\n description: 'Hundreds of models from many labs through one key.',\n keyUrl: 'https://openrouter.ai/settings/keys',\n cors: false,\n },\n {\n id: 'fireworks',\n make: fireworksProvider,\n env: 'FIREWORKS_API_KEY',\n description: 'Open models hosted by Fireworks AI.',\n keyUrl: 'https://app.fireworks.ai/settings/users/api-keys',\n cors: false,\n },\n {\n id: 'baseten',\n make: basetenProvider,\n env: 'BASETEN_API_KEY',\n description: 'Open models hosted by Baseten.',\n keyUrl: 'https://app.baseten.co/settings/api_keys',\n cors: true,\n },\n {\n id: 'moonshotai',\n make: moonshotaiProvider,\n env: 'MOONSHOT_API_KEY',\n description: 'Kimi models from Moonshot AI.',\n keyUrl: 'https://platform.moonshot.ai/console/api-keys',\n cors: true,\n },\n {\n id: 'moonshotai-cn',\n make: moonshotaiCnProvider,\n env: 'MOONSHOT_API_KEY',\n description: 'Kimi models from Moonshot AI\u2019s China platform.',\n keyUrl: 'https://platform.moonshot.cn/console/api-keys',\n cors: true,\n },\n {\n id: 'xai',\n make: xaiProvider,\n env: 'XAI_API_KEY',\n description: 'Grok models from xAI.',\n keyUrl: 'https://console.x.ai',\n cors: true,\n signIn: true,\n },\n {\n id: 'meta',\n make: metaProvider,\n env: 'META_API_KEY',\n description: 'Meta\u2019s Muse models.',\n keyUrl: 'https://developer.meta.ai',\n cors: true,\n },\n {\n id: 'vercel-ai-gateway',\n make: vercelAIGatewayProvider,\n env: 'AI_GATEWAY_API_KEY',\n description: 'Models from many labs through Vercel\u2019s AI Gateway.',\n keyUrl: 'https://vercel.com/docs/ai-gateway/authentication',\n cors: false,\n },\n {\n id: 'minimax',\n make: minimaxProvider,\n env: 'MINIMAX_API_KEY',\n description: 'MiniMax\u2019s models.',\n keyUrl: 'https://platform.minimax.io/user-center/basic-information/interface-key',\n cors: false,\n },\n {\n id: 'minimax-cn',\n make: minimaxCnProvider,\n env: 'MINIMAX_CN_API_KEY',\n description: 'MiniMax\u2019s models from its China platform.',\n keyUrl: 'https://platform.minimaxi.com/user-center/basic-information/interface-key',\n cors: false,\n },\n {\n id: 'zai',\n make: zaiProvider,\n env: 'ZAI_API_KEY',\n description: 'GLM models on Z.AI\u2019s coding plan.',\n keyUrl: 'https://z.ai/manage-apikey/apikey-list',\n cors: false,\n },\n {\n id: 'zai-coding-cn',\n make: zaiCodingCnProvider,\n env: 'ZAI_CODING_CN_API_KEY',\n description: 'GLM models on Zhipu\u2019s coding plan in China.',\n keyUrl: 'https://open.bigmodel.cn/usercenter/apikeys',\n cors: true,\n },\n {\n id: 'nvidia',\n make: nvidiaProvider,\n env: 'NVIDIA_API_KEY',\n description: 'Open models on NVIDIA\u2019s API catalog.',\n keyUrl: 'https://build.nvidia.com/settings/api-keys',\n cors: false,\n },\n {\n id: 'kimi-coding',\n make: kimiCodingProvider,\n env: 'KIMI_API_KEY',\n description: 'Kimi models on the Kimi Code subscription.',\n keyUrl: 'https://www.kimi.com/code/console',\n cors: false,\n signIn: true,\n },\n {\n id: 'ant-ling',\n make: antLingProvider,\n env: 'ANT_LING_API_KEY',\n description: 'Ling and Ring models from Ant Group.',\n keyUrl: 'https://www.ant-ling.com',\n cors: false,\n },\n {\n id: 'opencode',\n make: opencodeProvider,\n env: 'OPENCODE_API_KEY',\n description:\n 'Models curated for coding agents by OpenCode Zen. Needs seven\u2019s vault 1.12.2 or later.',\n keyUrl: 'https://opencode.ai/auth',\n cors: false,\n },\n {\n id: 'opencode-go',\n make: opencodeGoProvider,\n env: 'OPENCODE_API_KEY',\n description:\n 'Open models on the OpenCode Go subscription. Needs seven\u2019s vault 1.12.2 or later.',\n keyUrl: 'https://opencode.ai/auth',\n cors: false,\n },\n {\n id: 'qwen-token-plan',\n make: qwenTokenPlanProvider,\n env: 'QWEN_TOKEN_PLAN_API_KEY',\n description: 'Qwen models on an Alibaba Cloud token plan.',\n keyUrl: 'https://modelstudio.console.alibabacloud.com',\n cors: false,\n },\n {\n id: 'qwen-token-plan-cn',\n make: qwenTokenPlanCnProvider,\n env: 'QWEN_TOKEN_PLAN_CN_API_KEY',\n description: 'Qwen models on an Alibaba Cloud token plan in China.',\n keyUrl: 'https://bailian.console.aliyun.com',\n cors: false,\n },\n {\n id: 'qwen-token-plan-individual',\n make: qwenTokenPlanIndividualProvider,\n env: 'QWEN_TOKEN_PLAN_API_KEY',\n description: 'Qwen models on an individual Alibaba Cloud token plan.',\n keyUrl: 'https://modelstudio.console.alibabacloud.com',\n cors: false,\n },\n];\n\nexport type ProviderAuth = 'api-key' | 'oauth' | 'fields' | 'local';\n\nexport interface Listing {\n description: string;\n keyUrl?: string;\n auth: ProviderAuth;\n corsFree: boolean;\n vaultName: string;\n fields?: readonly FieldSpec[];\n}\n\nconst upper = (text: string) => text.toUpperCase().replace(/[^A-Z0-9]/g, '_');\n\nfunction vaultNames(entries: readonly KeyProvider[]): Map<string, string> {\n const uses = Map.groupBy(entries, (entry) => entry.env);\n return new Map(\n entries.map((entry) => [\n entry.id,\n (uses.get(entry.env) as KeyProvider[]).length > 1 ? `${upper(entry.id)}_API_KEY` : entry.env,\n ])\n );\n}\n\nconst named = vaultNames(KEY_PROVIDERS);\n\nexport const LISTINGS: ReadonlyMap<string, Listing> = new Map<string, Listing>([\n [\n 'amazon-bedrock',\n {\n description: 'Claude and other models on AWS, with a Bedrock API key.',\n keyUrl: 'https://console.aws.amazon.com/bedrock/home#/api-keys',\n auth: 'fields',\n corsFree: false,\n vaultName: 'AWS_BEARER_TOKEN_BEDROCK',\n fields: [REGION_FIELD],\n },\n ],\n [\n 'adobe',\n {\n description: 'Models through Adobe\u2019s LLM proxy, with your Adobe ID.',\n auth: 'oauth',\n corsFree: false,\n vaultName: 'ADOBE_IMS_TOKEN',\n },\n ],\n ...KEY_PROVIDERS.map((entry): [string, Listing] => [\n entry.id,\n {\n description: entry.description,\n keyUrl: entry.keyUrl,\n auth: entry.signIn ? 'oauth' : entry.fields ? 'fields' : 'api-key',\n corsFree: !entry.cors,\n vaultName: named.get(entry.id) as string,\n ...(entry.fields ? { fields: entry.fields } : {}),\n },\n ]),\n [\n CODEX,\n {\n description: 'GPT models on your ChatGPT Plus or Pro plan, with your ChatGPT account.',\n auth: 'oauth',\n corsFree: true,\n vaultName: 'OPENAI_CODEX_TOKEN',\n },\n ],\n]);\n\nexport const ADDED_FIRST: readonly string[] = ['amazon-bedrock', 'adobe'];\n"],
4
+ "sourcesContent": ["import type { Provider } from '@earendil-works/pi-ai';\nimport { antLingProvider } from '@earendil-works/pi-ai/providers/ant-ling';\nimport { anthropicProvider } from '@earendil-works/pi-ai/providers/anthropic';\nimport { azureProvider } from '@earendil-works/pi-ai/providers/azure';\nimport { basetenProvider } from '@earendil-works/pi-ai/providers/baseten';\nimport { cerebrasProvider } from '@earendil-works/pi-ai/providers/cerebras';\nimport { cloudflareAIGatewayProvider } from '@earendil-works/pi-ai/providers/cloudflare-ai-gateway';\nimport { cloudflareWorkersAIProvider } from '@earendil-works/pi-ai/providers/cloudflare-workers-ai';\nimport { deepseekProvider } from '@earendil-works/pi-ai/providers/deepseek';\nimport { fireworksProvider } from '@earendil-works/pi-ai/providers/fireworks';\nimport { groqProvider } from '@earendil-works/pi-ai/providers/groq';\nimport { huggingfaceProvider } from '@earendil-works/pi-ai/providers/huggingface';\nimport { kimiCodingProvider } from '@earendil-works/pi-ai/providers/kimi-coding';\nimport { metaProvider } from '@earendil-works/pi-ai/providers/meta';\nimport { minimaxProvider } from '@earendil-works/pi-ai/providers/minimax';\nimport { minimaxCnProvider } from '@earendil-works/pi-ai/providers/minimax-cn';\nimport { mistralProvider } from '@earendil-works/pi-ai/providers/mistral';\nimport { moonshotaiProvider } from '@earendil-works/pi-ai/providers/moonshotai';\nimport { moonshotaiCnProvider } from '@earendil-works/pi-ai/providers/moonshotai-cn';\nimport { nvidiaProvider } from '@earendil-works/pi-ai/providers/nvidia';\nimport { openaiProvider } from '@earendil-works/pi-ai/providers/openai';\nimport { opencodeProvider } from '@earendil-works/pi-ai/providers/opencode';\nimport { opencodeGoProvider } from '@earendil-works/pi-ai/providers/opencode-go';\nimport { openrouterProvider } from '@earendil-works/pi-ai/providers/openrouter';\nimport { qwenTokenPlanProvider } from '@earendil-works/pi-ai/providers/qwen-token-plan';\nimport { qwenTokenPlanCnProvider } from '@earendil-works/pi-ai/providers/qwen-token-plan-cn';\nimport { qwenTokenPlanIndividualProvider } from '@earendil-works/pi-ai/providers/qwen-token-plan-individual';\nimport { togetherProvider } from '@earendil-works/pi-ai/providers/together';\nimport { vercelAIGatewayProvider } from '@earendil-works/pi-ai/providers/vercel-ai-gateway';\nimport { xaiProvider } from '@earendil-works/pi-ai/providers/xai';\nimport { xiaomiProvider } from '@earendil-works/pi-ai/providers/xiaomi';\nimport { xiaomiTokenPlanAmsProvider } from '@earendil-works/pi-ai/providers/xiaomi-token-plan-ams';\nimport { xiaomiTokenPlanCnProvider } from '@earendil-works/pi-ai/providers/xiaomi-token-plan-cn';\nimport { xiaomiTokenPlanSgpProvider } from '@earendil-works/pi-ai/providers/xiaomi-token-plan-sgp';\nimport { zaiProvider } from '@earendil-works/pi-ai/providers/zai';\nimport { zaiCodingCnProvider } from '@earendil-works/pi-ai/providers/zai-coding-cn';\nimport { CODEX } from './sign-ins.ts';\n\nexport interface FieldOption {\n value: string;\n label: string;\n}\n\nexport interface FieldInput {\n name: string;\n label: string;\n required?: boolean;\n placeholder?: string;\n help?: string;\n customBase?: true;\n vaultSetting?: string;\n options?: readonly FieldOption[];\n value?: string;\n}\n\nexport interface FieldSpec extends FieldInput {\n env(value: string): Record<string, string> | string;\n}\n\nexport interface KeyProvider {\n id: string;\n make: () => Provider;\n env: string;\n description: string;\n keyUrl: string;\n cors: boolean;\n signIn?: true;\n fields?: readonly FieldSpec[];\n}\n\nconst RESOURCE = /^[a-z0-9][a-z0-9-]{0,62}$/i;\nconst DEPLOYMENTS = /^[^=,\\s]+\\s*=\\s*[^=,\\s]+(\\s*,\\s*[^=,\\s]+\\s*=\\s*[^=,\\s]+)*$/;\n\nexport function httpsBase(value: string): URL | undefined {\n const url = URL.parse(value);\n if (url?.protocol !== 'https:' || url.username || url.password) return undefined;\n return url.port === '' || url.port === '443' ? url : undefined;\n}\n\nfunction azureEndpoint(value: string): Record<string, string> | string {\n if (RESOURCE.test(value)) return { AZURE_OPENAI_RESOURCE_NAME: value };\n const url = httpsBase(value);\n if (!url)\n return 'Enter your Azure resource name, or its endpoint as an https:// address without a port or a user name.';\n return { AZURE_OPENAI_BASE_URL: url.href.replace(/\\/+$/, '') };\n}\n\nexport const AZURE = 'azure';\n\nexport function azureBase(env: Readonly<Record<string, string>>): string | undefined {\n if (env.AZURE_OPENAI_BASE_URL) return env.AZURE_OPENAI_BASE_URL;\n const name = env.AZURE_OPENAI_RESOURCE_NAME;\n return name ? `https://${name}.openai.azure.com/openai/v1` : undefined;\n}\n\nconst REGION = /^[a-z]{2,}(-[a-z]+)+-\\d{1,2}$/;\nconst ACCOUNT = /^[0-9a-f]{32}$/i;\nconst GATEWAY = /^[A-Za-z0-9_-]{1,64}$/;\n\nconst checked =\n (pattern: RegExp, env: string, problem: string) =>\n (value: string): Record<string, string> | string =>\n pattern.test(value) ? { [env]: value } : problem;\n\nconst BEDROCK_REGIONS: readonly (readonly [string, string])[] = [\n ['ap-northeast-1', 'Asia Pacific (Tokyo)'],\n ['ap-northeast-2', 'Asia Pacific (Seoul)'],\n ['ap-northeast-3', 'Asia Pacific (Osaka)'],\n ['ap-south-1', 'Asia Pacific (Mumbai)'],\n ['ap-south-2', 'Asia Pacific (Hyderabad)'],\n ['ap-southeast-1', 'Asia Pacific (Singapore)'],\n ['ap-southeast-2', 'Asia Pacific (Sydney)'],\n ['ca-central-1', 'Canada (Central)'],\n ['eu-central-1', 'Europe (Frankfurt)'],\n ['eu-central-2', 'Europe (Zurich)'],\n ['eu-north-1', 'Europe (Stockholm)'],\n ['eu-south-1', 'Europe (Milan)'],\n ['eu-south-2', 'Europe (Spain)'],\n ['eu-west-1', 'Europe (Ireland)'],\n ['eu-west-2', 'Europe (London)'],\n ['eu-west-3', 'Europe (Paris)'],\n ['sa-east-1', 'South America (S\u00E3o Paulo)'],\n ['us-east-1', 'US East (N. Virginia)'],\n ['us-gov-east-1', 'AWS GovCloud (US-East)'],\n ['us-gov-west-1', 'AWS GovCloud (US-West)'],\n ['us-west-2', 'US West (Oregon)'],\n];\n\nexport const DEFAULT_REGION = 'us-west-2';\n\nexport const REGION_FIELD: FieldSpec = {\n name: 'region',\n label: 'Region',\n help: 'The AWS region your Bedrock models run in.',\n options: BEDROCK_REGIONS.map(([value, label]) => ({ value, label: `${label}, ${value}` })),\n value: DEFAULT_REGION,\n env: checked(REGION, 'AWS_REGION', 'Enter an AWS region such as us-west-2.'),\n};\n\nconst ACCOUNT_FIELD: FieldSpec = {\n name: 'account',\n label: 'Account ID',\n required: true,\n placeholder: '0123456789abcdef0123456789abcdef',\n help: 'The 32-character ID on your Cloudflare dashboard\u2019s account overview.',\n vaultSetting: 'CLOUDFLARE_ACCOUNT_ID',\n env: checked(\n ACCOUNT,\n 'CLOUDFLARE_ACCOUNT_ID',\n 'A Cloudflare account ID is 32 characters of 0\u20139 and a\u2013f.'\n ),\n};\n\nexport const KEY_PROVIDERS: readonly KeyProvider[] = [\n {\n id: 'azure',\n make: azureProvider,\n env: 'AZURE_OPENAI_API_KEY',\n description: 'OpenAI models deployed in your own Azure OpenAI or AI Foundry resource.',\n keyUrl: 'https://portal.azure.com',\n cors: true,\n fields: [\n {\n name: 'endpoint',\n label: 'Endpoint',\n required: true,\n placeholder: 'my-resource or https://my-resource.openai.azure.com',\n help: 'Your resource\u2019s name, or its endpoint address from Keys and Endpoint.',\n customBase: true,\n vaultSetting: 'AZURE_OPENAI_RESOURCE_NAME',\n env: azureEndpoint,\n },\n {\n name: 'deployments',\n label: 'Deployments',\n placeholder: 'gpt-5.4=my-gpt',\n help: 'Only for deployments named differently from their model, as model=deployment, separated by commas.',\n env: (value) =>\n DEPLOYMENTS.test(value)\n ? { AZURE_OPENAI_DEPLOYMENT_NAME_MAP: value }\n : 'Write each deployment as model=deployment, separated by commas.',\n },\n ],\n },\n {\n id: 'cloudflare-workers-ai',\n make: cloudflareWorkersAIProvider,\n env: 'CLOUDFLARE_API_KEY',\n description: 'Open models on Cloudflare Workers AI, in your Cloudflare account.',\n keyUrl: 'https://dash.cloudflare.com/profile/api-tokens',\n cors: false,\n fields: [ACCOUNT_FIELD],\n },\n {\n id: 'cloudflare-ai-gateway',\n make: cloudflareAIGatewayProvider,\n env: 'CLOUDFLARE_API_KEY',\n description: 'Models from many labs through your Cloudflare AI Gateway.',\n keyUrl: 'https://dash.cloudflare.com/profile/api-tokens',\n cors: false,\n fields: [\n ACCOUNT_FIELD,\n {\n name: 'gateway',\n label: 'Gateway ID',\n required: true,\n placeholder: 'my-gateway',\n help: 'The name of your gateway under AI \u203A AI Gateway.',\n vaultSetting: 'CLOUDFLARE_GATEWAY_ID',\n env: checked(\n GATEWAY,\n 'CLOUDFLARE_GATEWAY_ID',\n 'A gateway ID is letters, digits, - and _, up to 64 characters.'\n ),\n },\n ],\n },\n {\n id: 'anthropic',\n make: anthropicProvider,\n env: 'ANTHROPIC_API_KEY',\n description: 'Claude models, with an API key from the Claude Console.',\n keyUrl: 'https://console.anthropic.com/settings/keys',\n cors: true,\n },\n {\n id: 'openai',\n make: openaiProvider,\n env: 'OPENAI_API_KEY',\n description: 'GPT models, with an API key from the OpenAI platform.',\n keyUrl: 'https://platform.openai.com/api-keys',\n cors: true,\n },\n {\n id: 'mistral',\n make: mistralProvider,\n env: 'MISTRAL_API_KEY',\n description: 'Mistral and Devstral models from La Plateforme.',\n keyUrl: 'https://console.mistral.ai/api-keys',\n cors: true,\n },\n {\n id: 'groq',\n make: groqProvider,\n env: 'GROQ_API_KEY',\n description: 'Open models on Groq\u2019s fast inference.',\n keyUrl: 'https://console.groq.com/keys',\n cors: true,\n },\n {\n id: 'deepseek',\n make: deepseekProvider,\n env: 'DEEPSEEK_API_KEY',\n description: 'DeepSeek\u2019s own models.',\n keyUrl: 'https://platform.deepseek.com/api_keys',\n cors: true,\n },\n {\n id: 'together',\n make: togetherProvider,\n env: 'TOGETHER_API_KEY',\n description: 'Open models hosted by Together AI.',\n keyUrl: 'https://api.together.ai/settings/api-keys',\n cors: true,\n },\n {\n id: 'huggingface',\n make: huggingfaceProvider,\n env: 'HF_TOKEN',\n description: 'Open models through Hugging Face\u2019s inference router.',\n keyUrl: 'https://huggingface.co/settings/tokens',\n cors: true,\n },\n {\n id: 'xiaomi',\n make: xiaomiProvider,\n env: 'XIAOMI_API_KEY',\n description: 'Xiaomi\u2019s MiMo models.',\n keyUrl: 'https://platform.xiaomimimo.com/#/console/api-keys',\n cors: true,\n },\n {\n id: 'xiaomi-token-plan-ams',\n make: xiaomiTokenPlanAmsProvider,\n env: 'XIAOMI_TOKEN_PLAN_AMS_API_KEY',\n description: 'MiMo models on a Xiaomi token plan, served from Amsterdam.',\n keyUrl: 'https://platform.xiaomimimo.com/#/console/api-keys',\n cors: true,\n },\n {\n id: 'xiaomi-token-plan-cn',\n make: xiaomiTokenPlanCnProvider,\n env: 'XIAOMI_TOKEN_PLAN_CN_API_KEY',\n description: 'MiMo models on a Xiaomi token plan, served from China.',\n keyUrl: 'https://platform.xiaomimimo.com/#/console/api-keys',\n cors: true,\n },\n {\n id: 'xiaomi-token-plan-sgp',\n make: xiaomiTokenPlanSgpProvider,\n env: 'XIAOMI_TOKEN_PLAN_SGP_API_KEY',\n description: 'MiMo models on a Xiaomi token plan, served from Singapore.',\n keyUrl: 'https://platform.xiaomimimo.com/#/console/api-keys',\n cors: true,\n },\n {\n id: 'cerebras',\n make: cerebrasProvider,\n env: 'CEREBRAS_API_KEY',\n description: 'Open models on Cerebras inference.',\n keyUrl: 'https://cloud.cerebras.ai',\n cors: false,\n },\n {\n id: 'openrouter',\n make: openrouterProvider,\n env: 'OPENROUTER_API_KEY',\n description: 'Hundreds of models from many labs through one key.',\n keyUrl: 'https://openrouter.ai/settings/keys',\n cors: false,\n },\n {\n id: 'fireworks',\n make: fireworksProvider,\n env: 'FIREWORKS_API_KEY',\n description: 'Open models hosted by Fireworks AI.',\n keyUrl: 'https://app.fireworks.ai/settings/users/api-keys',\n cors: false,\n },\n {\n id: 'baseten',\n make: basetenProvider,\n env: 'BASETEN_API_KEY',\n description: 'Open models hosted by Baseten.',\n keyUrl: 'https://app.baseten.co/settings/api_keys',\n cors: true,\n },\n {\n id: 'moonshotai',\n make: moonshotaiProvider,\n env: 'MOONSHOT_API_KEY',\n description: 'Kimi models from Moonshot AI.',\n keyUrl: 'https://platform.moonshot.ai/console/api-keys',\n cors: true,\n },\n {\n id: 'moonshotai-cn',\n make: moonshotaiCnProvider,\n env: 'MOONSHOT_API_KEY',\n description: 'Kimi models from Moonshot AI\u2019s China platform.',\n keyUrl: 'https://platform.moonshot.cn/console/api-keys',\n cors: true,\n },\n {\n id: 'xai',\n make: xaiProvider,\n env: 'XAI_API_KEY',\n description: 'Grok models from xAI.',\n keyUrl: 'https://console.x.ai',\n cors: true,\n signIn: true,\n },\n {\n id: 'meta',\n make: metaProvider,\n env: 'META_API_KEY',\n description: 'Meta\u2019s Muse models.',\n keyUrl: 'https://developer.meta.ai',\n cors: true,\n },\n {\n id: 'vercel-ai-gateway',\n make: vercelAIGatewayProvider,\n env: 'AI_GATEWAY_API_KEY',\n description: 'Models from many labs through Vercel\u2019s AI Gateway.',\n keyUrl: 'https://vercel.com/docs/ai-gateway/authentication',\n cors: false,\n },\n {\n id: 'minimax',\n make: minimaxProvider,\n env: 'MINIMAX_API_KEY',\n description: 'MiniMax\u2019s models.',\n keyUrl: 'https://platform.minimax.io/user-center/basic-information/interface-key',\n cors: false,\n },\n {\n id: 'minimax-cn',\n make: minimaxCnProvider,\n env: 'MINIMAX_CN_API_KEY',\n description: 'MiniMax\u2019s models from its China platform.',\n keyUrl: 'https://platform.minimaxi.com/user-center/basic-information/interface-key',\n cors: false,\n },\n {\n id: 'zai',\n make: zaiProvider,\n env: 'ZAI_API_KEY',\n description: 'GLM models on Z.AI\u2019s coding plan.',\n keyUrl: 'https://z.ai/manage-apikey/apikey-list',\n cors: false,\n },\n {\n id: 'zai-coding-cn',\n make: zaiCodingCnProvider,\n env: 'ZAI_CODING_CN_API_KEY',\n description: 'GLM models on Zhipu\u2019s coding plan in China.',\n keyUrl: 'https://open.bigmodel.cn/usercenter/apikeys',\n cors: false,\n },\n {\n id: 'nvidia',\n make: nvidiaProvider,\n env: 'NVIDIA_API_KEY',\n description: 'Open models on NVIDIA\u2019s API catalog.',\n keyUrl: 'https://build.nvidia.com/settings/api-keys',\n cors: false,\n },\n {\n id: 'kimi-coding',\n make: kimiCodingProvider,\n env: 'KIMI_API_KEY',\n description: 'Kimi models on the Kimi Code subscription.',\n keyUrl: 'https://www.kimi.com/code/console',\n cors: false,\n signIn: true,\n },\n {\n id: 'ant-ling',\n make: antLingProvider,\n env: 'ANT_LING_API_KEY',\n description: 'Ling and Ring models from Ant Group.',\n keyUrl: 'https://www.ant-ling.com',\n cors: false,\n },\n {\n id: 'opencode',\n make: opencodeProvider,\n env: 'OPENCODE_API_KEY',\n description:\n 'Models curated for coding agents by OpenCode Zen. Needs seven\u2019s vault 1.12.2 or later.',\n keyUrl: 'https://opencode.ai/auth',\n cors: false,\n },\n {\n id: 'opencode-go',\n make: opencodeGoProvider,\n env: 'OPENCODE_API_KEY',\n description:\n 'Open models on the OpenCode Go subscription. Needs seven\u2019s vault 1.12.2 or later.',\n keyUrl: 'https://opencode.ai/auth',\n cors: false,\n },\n {\n id: 'qwen-token-plan',\n make: qwenTokenPlanProvider,\n env: 'QWEN_TOKEN_PLAN_API_KEY',\n description: 'Qwen models on an Alibaba Cloud token plan.',\n keyUrl: 'https://modelstudio.console.alibabacloud.com',\n cors: false,\n },\n {\n id: 'qwen-token-plan-cn',\n make: qwenTokenPlanCnProvider,\n env: 'QWEN_TOKEN_PLAN_CN_API_KEY',\n description: 'Qwen models on an Alibaba Cloud token plan in China.',\n keyUrl: 'https://bailian.console.aliyun.com',\n cors: false,\n },\n {\n id: 'qwen-token-plan-individual',\n make: qwenTokenPlanIndividualProvider,\n env: 'QWEN_TOKEN_PLAN_API_KEY',\n description: 'Qwen models on an individual Alibaba Cloud token plan.',\n keyUrl: 'https://modelstudio.console.alibabacloud.com',\n cors: false,\n },\n];\n\nexport type ProviderAuth = 'api-key' | 'oauth' | 'fields' | 'local';\n\nexport interface Listing {\n description: string;\n keyUrl?: string;\n auth: ProviderAuth;\n corsFree: boolean;\n vaultName: string;\n fields?: readonly FieldSpec[];\n}\n\nconst upper = (text: string) => text.toUpperCase().replace(/[^A-Z0-9]/g, '_');\n\nfunction vaultNames(entries: readonly KeyProvider[]): Map<string, string> {\n const uses = Map.groupBy(entries, (entry) => entry.env);\n return new Map(\n entries.map((entry) => [\n entry.id,\n (uses.get(entry.env) as KeyProvider[]).length > 1 ? `${upper(entry.id)}_API_KEY` : entry.env,\n ])\n );\n}\n\nconst named = vaultNames(KEY_PROVIDERS);\n\nexport const LISTINGS: ReadonlyMap<string, Listing> = new Map<string, Listing>([\n [\n 'amazon-bedrock',\n {\n description: 'Claude and other models on AWS, with a Bedrock API key.',\n keyUrl: 'https://console.aws.amazon.com/bedrock/home#/api-keys',\n auth: 'fields',\n corsFree: false,\n vaultName: 'AWS_BEARER_TOKEN_BEDROCK',\n fields: [REGION_FIELD],\n },\n ],\n [\n 'adobe',\n {\n description: 'Models through Adobe\u2019s LLM proxy, with your Adobe ID.',\n auth: 'oauth',\n corsFree: false,\n vaultName: 'ADOBE_IMS_TOKEN',\n },\n ],\n ...KEY_PROVIDERS.map((entry): [string, Listing] => [\n entry.id,\n {\n description: entry.description,\n keyUrl: entry.keyUrl,\n auth: entry.signIn ? 'oauth' : entry.fields ? 'fields' : 'api-key',\n corsFree: !entry.cors,\n vaultName: named.get(entry.id) as string,\n ...(entry.fields ? { fields: entry.fields } : {}),\n },\n ]),\n [\n CODEX,\n {\n description: 'GPT models on your ChatGPT Plus or Pro plan, with your ChatGPT account.',\n auth: 'oauth',\n corsFree: true,\n vaultName: 'OPENAI_CODEX_TOKEN',\n },\n ],\n]);\n\nexport const ADDED_FIRST: readonly string[] = ['amazon-bedrock', 'adobe'];\n"],
5
5
  "mappings": "AACA,SAAS,uBAAuB;AAChC,SAAS,yBAAyB;AAClC,SAAS,qBAAqB;AAC9B,SAAS,uBAAuB;AAChC,SAAS,wBAAwB;AACjC,SAAS,mCAAmC;AAC5C,SAAS,mCAAmC;AAC5C,SAAS,wBAAwB;AACjC,SAAS,yBAAyB;AAClC,SAAS,oBAAoB;AAC7B,SAAS,2BAA2B;AACpC,SAAS,0BAA0B;AACnC,SAAS,oBAAoB;AAC7B,SAAS,uBAAuB;AAChC,SAAS,yBAAyB;AAClC,SAAS,uBAAuB;AAChC,SAAS,0BAA0B;AACnC,SAAS,4BAA4B;AACrC,SAAS,sBAAsB;AAC/B,SAAS,sBAAsB;AAC/B,SAAS,wBAAwB;AACjC,SAAS,0BAA0B;AACnC,SAAS,0BAA0B;AACnC,SAAS,6BAA6B;AACtC,SAAS,+BAA+B;AACxC,SAAS,uCAAuC;AAChD,SAAS,wBAAwB;AACjC,SAAS,+BAA+B;AACxC,SAAS,mBAAmB;AAC5B,SAAS,sBAAsB;AAC/B,SAAS,kCAAkC;AAC3C,SAAS,iCAAiC;AAC1C,SAAS,kCAAkC;AAC3C,SAAS,mBAAmB;AAC5B,SAAS,2BAA2B;AACpC,SAAS,aAAa;AAkCtB,MAAM,WAAW;AACjB,MAAM,cAAc;AAEb,SAAS,UAAU,OAAgC;AACxD,QAAM,MAAM,IAAI,MAAM,KAAK;AAC3B,MAAI,KAAK,aAAa,YAAY,IAAI,YAAY,IAAI,SAAU,QAAO;AACvE,SAAO,IAAI,SAAS,MAAM,IAAI,SAAS,QAAQ,MAAM;AACvD;AAEA,SAAS,cAAc,OAAgD;AACrE,MAAI,SAAS,KAAK,KAAK,EAAG,QAAO,EAAE,4BAA4B,MAAM;AACrE,QAAM,MAAM,UAAU,KAAK;AAC3B,MAAI,CAAC;AACH,WAAO;AACT,SAAO,EAAE,uBAAuB,IAAI,KAAK,QAAQ,QAAQ,EAAE,EAAE;AAC/D;AAEO,MAAM,QAAQ;AAEd,SAAS,UAAU,KAA2D;AACnF,MAAI,IAAI,sBAAuB,QAAO,IAAI;AAC1C,QAAM,OAAO,IAAI;AACjB,SAAO,OAAO,WAAW,IAAI,gCAAgC;AAC/D;AAEA,MAAM,SAAS;AACf,MAAM,UAAU;AAChB,MAAM,UAAU;AAEhB,MAAM,UACJ,CAAC,SAAiB,KAAa,YAC/B,CAAC,UACC,QAAQ,KAAK,KAAK,IAAI,EAAE,CAAC,GAAG,GAAG,MAAM,IAAI;AAE7C,MAAM,kBAA0D;AAAA,EAC9D,CAAC,kBAAkB,sBAAsB;AAAA,EACzC,CAAC,kBAAkB,sBAAsB;AAAA,EACzC,CAAC,kBAAkB,sBAAsB;AAAA,EACzC,CAAC,cAAc,uBAAuB;AAAA,EACtC,CAAC,cAAc,0BAA0B;AAAA,EACzC,CAAC,kBAAkB,0BAA0B;AAAA,EAC7C,CAAC,kBAAkB,uBAAuB;AAAA,EAC1C,CAAC,gBAAgB,kBAAkB;AAAA,EACnC,CAAC,gBAAgB,oBAAoB;AAAA,EACrC,CAAC,gBAAgB,iBAAiB;AAAA,EAClC,CAAC,cAAc,oBAAoB;AAAA,EACnC,CAAC,cAAc,gBAAgB;AAAA,EAC/B,CAAC,cAAc,gBAAgB;AAAA,EAC/B,CAAC,aAAa,kBAAkB;AAAA,EAChC,CAAC,aAAa,iBAAiB;AAAA,EAC/B,CAAC,aAAa,gBAAgB;AAAA,EAC9B,CAAC,aAAa,8BAA2B;AAAA,EACzC,CAAC,aAAa,uBAAuB;AAAA,EACrC,CAAC,iBAAiB,wBAAwB;AAAA,EAC1C,CAAC,iBAAiB,wBAAwB;AAAA,EAC1C,CAAC,aAAa,kBAAkB;AAClC;AAEO,MAAM,iBAAiB;AAEvB,MAAM,eAA0B;AAAA,EACrC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,MAAM;AAAA,EACN,SAAS,gBAAgB,IAAI,CAAC,CAAC,OAAO,KAAK,OAAO,EAAE,OAAO,OAAO,GAAG,KAAK,KAAK,KAAK,GAAG,EAAE;AAAA,EACzF,OAAO;AAAA,EACP,KAAK,QAAQ,QAAQ,cAAc,wCAAwC;AAC7E;AAEA,MAAM,gBAA2B;AAAA,EAC/B,MAAM;AAAA,EACN,OAAO;AAAA,EACP,UAAU;AAAA,EACV,aAAa;AAAA,EACb,MAAM;AAAA,EACN,cAAc;AAAA,EACd,KAAK;AAAA,IACH;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEO,MAAM,gBAAwC;AAAA,EACnD;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,KAAK;AAAA,IACL,aAAa;AAAA,IACb,QAAQ;AAAA,IACR,MAAM;AAAA,IACN,QAAQ;AAAA,MACN;AAAA,QACE,MAAM;AAAA,QACN,OAAO;AAAA,QACP,UAAU;AAAA,QACV,aAAa;AAAA,QACb,MAAM;AAAA,QACN,YAAY;AAAA,QACZ,cAAc;AAAA,QACd,KAAK;AAAA,MACP;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,OAAO;AAAA,QACP,aAAa;AAAA,QACb,MAAM;AAAA,QACN,KAAK,CAAC,UACJ,YAAY,KAAK,KAAK,IAClB,EAAE,kCAAkC,MAAM,IAC1C;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,KAAK;AAAA,IACL,aAAa;AAAA,IACb,QAAQ;AAAA,IACR,MAAM;AAAA,IACN,QAAQ,CAAC,aAAa;AAAA,EACxB;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,KAAK;AAAA,IACL,aAAa;AAAA,IACb,QAAQ;AAAA,IACR,MAAM;AAAA,IACN,QAAQ;AAAA,MACN;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,OAAO;AAAA,QACP,UAAU;AAAA,QACV,aAAa;AAAA,QACb,MAAM;AAAA,QACN,cAAc;AAAA,QACd,KAAK;AAAA,UACH;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,KAAK;AAAA,IACL,aAAa;AAAA,IACb,QAAQ;AAAA,IACR,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,KAAK;AAAA,IACL,aAAa;AAAA,IACb,QAAQ;AAAA,IACR,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,KAAK;AAAA,IACL,aAAa;AAAA,IACb,QAAQ;AAAA,IACR,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,KAAK;AAAA,IACL,aAAa;AAAA,IACb,QAAQ;AAAA,IACR,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,KAAK;AAAA,IACL,aAAa;AAAA,IACb,QAAQ;AAAA,IACR,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,KAAK;AAAA,IACL,aAAa;AAAA,IACb,QAAQ;AAAA,IACR,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,KAAK;AAAA,IACL,aAAa;AAAA,IACb,QAAQ;AAAA,IACR,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,KAAK;AAAA,IACL,aAAa;AAAA,IACb,QAAQ;AAAA,IACR,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,KAAK;AAAA,IACL,aAAa;AAAA,IACb,QAAQ;AAAA,IACR,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,KAAK;AAAA,IACL,aAAa;AAAA,IACb,QAAQ;AAAA,IACR,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,KAAK;AAAA,IACL,aAAa;AAAA,IACb,QAAQ;AAAA,IACR,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,KAAK;AAAA,IACL,aAAa;AAAA,IACb,QAAQ;AAAA,IACR,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,KAAK;AAAA,IACL,aAAa;AAAA,IACb,QAAQ;AAAA,IACR,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,KAAK;AAAA,IACL,aAAa;AAAA,IACb,QAAQ;AAAA,IACR,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,KAAK;AAAA,IACL,aAAa;AAAA,IACb,QAAQ;AAAA,IACR,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,KAAK;AAAA,IACL,aAAa;AAAA,IACb,QAAQ;AAAA,IACR,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,KAAK;AAAA,IACL,aAAa;AAAA,IACb,QAAQ;AAAA,IACR,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,KAAK;AAAA,IACL,aAAa;AAAA,IACb,QAAQ;AAAA,IACR,MAAM;AAAA,IACN,QAAQ;AAAA,EACV;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,KAAK;AAAA,IACL,aAAa;AAAA,IACb,QAAQ;AAAA,IACR,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,KAAK;AAAA,IACL,aAAa;AAAA,IACb,QAAQ;AAAA,IACR,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,KAAK;AAAA,IACL,aAAa;AAAA,IACb,QAAQ;AAAA,IACR,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,KAAK;AAAA,IACL,aAAa;AAAA,IACb,QAAQ;AAAA,IACR,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,KAAK;AAAA,IACL,aAAa;AAAA,IACb,QAAQ;AAAA,IACR,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,KAAK;AAAA,IACL,aAAa;AAAA,IACb,QAAQ;AAAA,IACR,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,KAAK;AAAA,IACL,aAAa;AAAA,IACb,QAAQ;AAAA,IACR,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,KAAK;AAAA,IACL,aAAa;AAAA,IACb,QAAQ;AAAA,IACR,MAAM;AAAA,IACN,QAAQ;AAAA,EACV;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,KAAK;AAAA,IACL,aAAa;AAAA,IACb,QAAQ;AAAA,IACR,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,KAAK;AAAA,IACL,aACE;AAAA,IACF,QAAQ;AAAA,IACR,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,KAAK;AAAA,IACL,aACE;AAAA,IACF,QAAQ;AAAA,IACR,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,KAAK;AAAA,IACL,aAAa;AAAA,IACb,QAAQ;AAAA,IACR,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,KAAK;AAAA,IACL,aAAa;AAAA,IACb,QAAQ;AAAA,IACR,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,KAAK;AAAA,IACL,aAAa;AAAA,IACb,QAAQ;AAAA,IACR,MAAM;AAAA,EACR;AACF;AAaA,MAAM,QAAQ,CAAC,SAAiB,KAAK,YAAY,EAAE,QAAQ,cAAc,GAAG;AAE5E,SAAS,WAAW,SAAsD;AACxE,QAAM,OAAO,IAAI,QAAQ,SAAS,CAAC,UAAU,MAAM,GAAG;AACtD,SAAO,IAAI;AAAA,IACT,QAAQ,IAAI,CAAC,UAAU;AAAA,MACrB,MAAM;AAAA,MACL,KAAK,IAAI,MAAM,GAAG,EAAoB,SAAS,IAAI,GAAG,MAAM,MAAM,EAAE,CAAC,aAAa,MAAM;AAAA,IAC3F,CAAC;AAAA,EACH;AACF;AAEA,MAAM,QAAQ,WAAW,aAAa;AAE/B,MAAM,WAAyC,IAAI,IAAqB;AAAA,EAC7E;AAAA,IACE;AAAA,IACA;AAAA,MACE,aAAa;AAAA,MACb,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,UAAU;AAAA,MACV,WAAW;AAAA,MACX,QAAQ,CAAC,YAAY;AAAA,IACvB;AAAA,EACF;AAAA,EACA;AAAA,IACE;AAAA,IACA;AAAA,MACE,aAAa;AAAA,MACb,MAAM;AAAA,MACN,UAAU;AAAA,MACV,WAAW;AAAA,IACb;AAAA,EACF;AAAA,EACA,GAAG,cAAc,IAAI,CAAC,UAA6B;AAAA,IACjD,MAAM;AAAA,IACN;AAAA,MACE,aAAa,MAAM;AAAA,MACnB,QAAQ,MAAM;AAAA,MACd,MAAM,MAAM,SAAS,UAAU,MAAM,SAAS,WAAW;AAAA,MACzD,UAAU,CAAC,MAAM;AAAA,MACjB,WAAW,MAAM,IAAI,MAAM,EAAE;AAAA,MAC7B,GAAI,MAAM,SAAS,EAAE,QAAQ,MAAM,OAAO,IAAI,CAAC;AAAA,IACjD;AAAA,EACF,CAAC;AAAA,EACD;AAAA,IACE;AAAA,IACA;AAAA,MACE,aAAa;AAAA,MACb,MAAM;AAAA,MACN,UAAU;AAAA,MACV,WAAW;AAAA,IACb;AAAA,EACF;AACF,CAAC;AAEM,MAAM,cAAiC,CAAC,kBAAkB,OAAO;",
6
6
  "names": []
7
7
  }
@@ -12,6 +12,7 @@ import { distinctTaints, runTaints } from "../guests/guard.js";
12
12
  import { HOME } from "../kernel/env.js";
13
13
  import { normalize, resolve } from "../kernel/paths.js";
14
14
  import { LEGACY } from "../layout.js";
15
+ import { pauseUntil } from "../pause.js";
15
16
  import { FROM_KIND } from "./from.js";
16
17
  import { ScoopWorkDoc } from "./service.js";
17
18
  import { cardOf } from "./summary.js";
@@ -103,7 +104,7 @@ function waitTask(lookup) {
103
104
  const open = state.scoops.filter((id) => !(id in state.done) && feeding.has(id));
104
105
  const expired = runtime.now() >= task.input.deadline;
105
106
  if (open.length && !expired) {
106
- await runtime.sleep(Math.min(runtime.now() + 300, task.input.deadline), context);
107
+ await pauseUntil(runtime, Math.min(runtime.now() + 300, task.input.deadline), context);
107
108
  continue;
108
109
  }
109
110
  const names = (id) => agents.state().scoops[id]?.name ?? id;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/scoops/extension.ts"],
4
- "sourcesContent": ["import type { Context } from '@earendil-works/chord';\nimport {\n AssistantEntry,\n type ConversationId,\n defineExtension,\n defineTask,\n type Extension,\n hook,\n type PromptInput,\n type Submission,\n section,\n ToolTask,\n type Tx,\n} from '@earendil-works/pi-durable';\nimport { answerText } from '../agent.ts';\nimport { AgentsDoc, type AgentsState, live, type ScoopRecord } from '../agents.ts';\nimport { distinctTaints, type InheritedTaint, runTaints } from '../guests/guard.ts';\nimport { HOME } from '../kernel/env.ts';\nimport { normalize, resolve } from '../kernel/paths.ts';\nimport { type Layout, LEGACY } from '../layout.ts';\nimport type { LickEvent } from '../licks/licks.ts';\nimport { FROM_KIND } from './from.ts';\nimport { type Feed, type ScoopsHost, ScoopWorkDoc } from './service.ts';\nimport { cardOf } from './summary.ts';\n\nexport const PREVIEW = 1000;\n\ntype Lookup = () => Promise<ScoopsHost>;\n\nexport async function scoopTainted(\n host: Pick<ScoopsHost, 'harness'>,\n state: Readonly<AgentsState>,\n scoops: readonly string[],\n event: LickEvent,\n context: Context,\n extra: readonly InheritedTaint[] = []\n): Promise<LickEvent> {\n const found: InheritedTaint[] = [...extra];\n for (const id of scoops) {\n const conversation = state.scoops[id]?.conversation;\n if (conversation !== undefined)\n found.push(...(await runTaints(host.harness, conversation as ConversationId, context)));\n }\n const taints = distinctTaints(found);\n return taints.length ? { ...event, taints } : event;\n}\n\nexport function scoopFacts(\n record: Pick<ScoopRecord, 'name' | 'folder' | 'role'> & { cone?: string },\n layout: Layout = LEGACY\n): string {\n const place = layout.workspace(record.folder);\n return [\n `You are the scoop \"${record.name}\"${record.role ? ` (role: ${record.role})` : ''}, a helper agent working for a cone. Messages come from the cone or from the user at a terminal; your final answer goes back to whoever asked, so end every task with a complete answer.`,\n layout.users\n ? `You run as the user ${layout.scoopRoot(record.folder).slice('/home/'.length)}, and your home is ${place}: work there. Your cone can read your home; you can't read your cone's home or another scoop's. /tmp is shared scratch.`\n : `Work in ${place}. Your read, write and edit tools only reach ${layout.scoopRoot(record.folder)} and /tmp, and read ${HOME}.`,\n layout.users\n ? 'Your bash runs as your user too, so the kernel decides what it may read and change. Stay in your home, and change nothing outside it unless the request says so.'\n : 'Your bash is not confined: it sees the whole file system and every process. Stay in your folder anyway, and change nothing outside it unless the request says so.',\n 'You may run `agent` synchronously for a bounded side task (calls nest at most three deep), but you cannot start asynchronous scoops (`agent --async`, `subagent spawn`).',\n ].join('\\n');\n}\n\nfunction lines(text: string): number {\n return text ? text.split('\\n').length : 0;\n}\n\nexport type ReportResult = { text: string; failed: string | null; path: string | null };\n\nexport function reportLick(\n record: ScoopRecord,\n id: string,\n report: ReportResult,\n route: { target?: string | null; channel?: 'scoop-notify' | 'bash' } = {}\n): LickEvent {\n const status = report.failed ? (report.failed === 'aborted' ? 'stopped' : 'failed') : 'completed';\n const label = `${record.name} (${record.role ?? 'scoop'})`;\n const preview = report.text.length > PREVIEW ? `${report.text.slice(0, PREVIEW)}\u2026` : report.text;\n const where = report.path ? `Output: ${report.path} (${lines(report.text)} lines)` : null;\n const reason = report.failed && report.failed !== 'aborted' ? `Reason: ${report.failed}` : null;\n return {\n channel: route.channel ?? 'scoop-notify',\n source: id,\n title: label,\n text: `[scoop ${record.name} (${record.role ?? 'scoop'}) ${status}]`,\n body: [where, reason, preview].filter(Boolean).join('\\n\\n'),\n target: (route.target ?? `cone:${record.cone}`) as LickEvent['target'],\n ...cardOf(record.name, report),\n ...(report.failed && report.failed !== 'aborted' ? { severity: 'warn' as const } : {}),\n };\n}\n\ntype Noting = {\n commit: (\n write: (\n tx: Tx\n ) => Promise<{ status: 'running'; checkpoint: { phase: 'deliver'; noted: true } }>,\n context: Context\n ) => Promise<unknown>;\n};\n\nexport async function noteWhenPlaced(\n runtime: Noting,\n submission: Pick<Submission, 'status'>,\n conversation: ConversationId,\n note: { from: string | undefined; agent?: boolean; noted: boolean | undefined },\n context: Context\n): Promise<void> {\n const { from } = note;\n while (from && !note.noted && !context.abortSignal?.aborted) {\n const record = await submission.status(context);\n if (record.status !== 'queued') {\n if (!('entry' in record) || record.entry === undefined) return;\n const entry = record.entry;\n await runtime\n .commit(async (tx) => {\n await tx.appendEntry(conversation, {\n kind: FROM_KIND,\n data: { from, entry, ...(note.agent ? { agent: true } : {}) },\n });\n return { status: 'running', checkpoint: { phase: 'deliver', noted: true } };\n }, context)\n .catch(() => undefined);\n return;\n }\n await new Promise((done) => setTimeout(done, NOTE_POLL_MS));\n }\n}\n\nexport const NOTE_POLL_MS = 100;\n\nexport function waitTask(lookup: Lookup) {\n type WaitInput = {\n scoops: string[];\n cone: string;\n deadline: number;\n taints?: InheritedTaint[];\n };\n\n return defineTask<WaitInput, { phase: 'start' } | { phase: 'watch' }, null>({\n name: 'slicc.scoop-wait',\n version: 1,\n initial: () => ({ phase: 'start' }),\n phases: {\n async start(task, runtime, context) {\n await runtime.commit(async (tx) => {\n (await tx.doc(ScoopWorkDoc)).waits[String(task.id)] = {\n scoops: task.input.scoops,\n done: {},\n cone: task.input.cone,\n };\n return { status: 'running', checkpoint: { phase: 'watch' } };\n }, context);\n },\n async watch(task, runtime, context) {\n const host = await lookup();\n const { agents, licks } = host;\n const key = String(task.id);\n for (;;) {\n const work = await runtime.snapshot(ScoopWorkDoc, context);\n const state = work?.waits[key];\n if (!state) break;\n const feeding = new Set(Object.values(work?.feeds ?? {}).map((feed) => feed.scoop));\n const open = state.scoops.filter((id) => !(id in state.done) && feeding.has(id));\n const expired = runtime.now() >= task.input.deadline;\n if (open.length && !expired) {\n await runtime.sleep(Math.min(runtime.now() + 300, task.input.deadline), context);\n continue;\n }\n const names = (id: string) => agents.state().scoops[id]?.name ?? id;\n const body = state.scoops.map((id) =>\n open.includes(id)\n ? `## ${names(id)}\\n(still working when the wait timed out)`\n : `## ${names(id)}\\n${state.done[id] ?? '(nothing was running)'}`\n );\n const lick: LickEvent = {\n channel: 'scoop-wait',\n source: key,\n title: `Waited for ${state.scoops.map(names).join(', ')}`,\n text: open.length\n ? `${state.scoops.length - open.length} of ${state.scoops.length} done; timed out waiting for ${open.map(names).join(', ')}`\n : `All ${state.scoops.length} done`,\n body: body.join('\\n\\n'),\n target: `cone:${state.cone}`,\n coalesce: false,\n eventId: `wait:${key}`,\n };\n await licks.deliver(\n await scoopTainted(\n host,\n agents.state(),\n state.scoops,\n lick,\n context,\n task.input.taints\n ),\n context\n );\n break;\n }\n await runtime.commit(async (tx) => {\n delete (await tx.doc(ScoopWorkDoc)).waits[key];\n return { status: 'terminal', outcome: { status: 'completed', result: null } };\n }, context);\n },\n },\n abort: (task, runtime, context) =>\n runtime.commit(async (tx) => {\n delete (await tx.doc(ScoopWorkDoc)).waits[String(task.id)];\n return { status: 'terminal', outcome: { status: 'aborted' } };\n }, context),\n });\n}\n\nexport function scoopTasks(lookup: Lookup) {\n const anchor = defineTask<null, { phase: 'done' }, null>({\n name: 'slicc.scoop-anchor',\n version: 1,\n initial: () => ({ phase: 'done' }),\n phases: {\n done: (_task, runtime, context) =>\n runtime.commit(\n () => ({ status: 'terminal', outcome: { status: 'completed', result: null } }),\n context\n ),\n },\n abort: (_task, runtime, context) =>\n runtime.commit(() => ({ status: 'terminal', outcome: { status: 'aborted' } }), context),\n });\n\n type ReporterInput = {\n scoop: string;\n prompt: string;\n followUp?: boolean;\n request?: string;\n };\n type ReporterState =\n | { phase: 'deliver'; noted?: boolean }\n | { phase: 'report'; text: string; failed: string | null };\n\n const reporter = defineTask<ReporterInput, ReporterState, ReportResult>({\n name: 'slicc.scoop-reporter',\n version: 1,\n initial: () => ({ phase: 'deliver' }),\n phases: {\n async deliver(task, runtime, context) {\n const { agents } = await lookup();\n const record = agents.state().scoops[task.input.scoop];\n const handle =\n record && live(record)\n ? await runtime.conversation(record.conversation as ConversationId, context)\n : undefined;\n if (!handle) {\n await runtime.commit(async (tx) => {\n delete (await tx.doc(ScoopWorkDoc)).feeds[String(task.id)];\n return {\n status: 'terminal',\n outcome: {\n status: 'completed',\n result: { text: '', failed: 'the scoop is gone', path: null },\n },\n };\n }, context);\n return;\n }\n const requestId = task.input.request ? `subagent:${task.input.request}` : `feed:${task.id}`;\n const feed = (await runtime.snapshot(ScoopWorkDoc, context))?.feeds[String(task.id)];\n const submission = await handle.submit(\n {\n type: 'input',\n content: task.input.prompt,\n whenBusy: task.input.followUp ? 'followUp' : 'steer',\n requestId,\n },\n context\n );\n const noting = noteWhenPlaced(\n runtime,\n submission,\n record?.conversation as ConversationId,\n { from: feed?.from, agent: feed?.agent === true, noted: task.state.checkpoint.noted },\n context\n );\n const settled = await submission.wait(context);\n await noting;\n await runtime.commit(async (tx) => {\n if (settled.status !== 'done' || settled.type !== 'input')\n return {\n status: 'running',\n checkpoint: {\n phase: 'report',\n text: '',\n failed: String(settled.reason),\n },\n };\n const answer = await tx.entry(AssistantEntry, settled.answer);\n return {\n status: 'running',\n checkpoint: {\n phase: 'report',\n text: answerText(answer?.model?.[0]?.content),\n failed: null,\n },\n };\n }, context);\n },\n async report(task, runtime, context) {\n const host = await lookup();\n const { agents, licks, layout = LEGACY } = host;\n const id = task.input.scoop;\n const record = agents.state().scoops[id];\n const { text, failed } = task.state.checkpoint;\n const path =\n record && text ? `${layout.reports(record.folder, record.cone)}/${task.id}.md` : null;\n if (path)\n await (await runtime.env(context))?.writeFile(\n path,\n text.endsWith('\\n') ? text : `${text}\\n`,\n context\n );\n const work = await runtime.snapshot(ScoopWorkDoc, context);\n const entry = work?.feeds[String(task.id)] as Feed;\n const waiting = (wait: { scoops: string[]; done: Record<string, string> }) =>\n wait.scoops.includes(id) && !(id in wait.done);\n const folded = Object.values(work?.waits ?? {}).some(waiting);\n const route = { target: entry.target, channel: entry.channel };\n if (!folded && record && entry.report && failed !== 'aborted')\n await licks.deliver(\n await scoopTainted(\n host,\n agents.state(),\n [id],\n {\n ...reportLick(record, id, { text, failed, path }, route),\n eventId: `report:${task.id}`,\n },\n context\n ),\n context\n );\n await runtime.commit(async (tx) => {\n const work = await tx.doc(ScoopWorkDoc);\n for (const wait of Object.values(work.waits))\n if (waiting(wait))\n wait.done[id] = failed\n ? `stopped: ${failed}`\n : `${path ? `Output: ${path}\\n` : ''}${text || '(no text)'}`;\n delete work.feeds[String(task.id)];\n return {\n status: 'terminal',\n outcome: { status: 'completed', result: { text, failed, path } },\n };\n }, context);\n },\n },\n abort: (task, runtime, context) =>\n runtime.commit(async (tx) => {\n delete (await tx.doc(ScoopWorkDoc)).feeds[String(task.id)];\n return { status: 'terminal', outcome: { status: 'aborted' } };\n }, context),\n });\n\n return { anchor, reporter, wait: waitTask(lookup) };\n}\n\nasync function whose(input: PromptInput, context: Context) {\n const state = await input.read.snapshot(AgentsDoc, context);\n const scoop = Object.values(state?.scoops ?? {}).find(\n (record) => record.conversation === input.conversationId\n );\n return { scoop };\n}\n\nexport function scoopsExtension(\n tasks: ReturnType<typeof scoopTasks>,\n layout: () => Layout = () => LEGACY\n): Extension {\n return defineExtension({\n name: 'slicc-scoops',\n tasks: [tasks.anchor, tasks.reporter, tasks.wait],\n sections: [\n section('scoop', async (input, context) => {\n const { scoop } = await whose(input, context);\n return scoop ? scoopFacts(scoop, layout()) : undefined;\n }),\n ],\n });\n}\n\nconst WRITES = new Set(['write', 'edit']);\n\nexport function allowed(\n record: Pick<ScoopRecord, 'folder'> & { roots?: ScoopRecord['roots'] },\n coneCwd: string,\n path: string,\n writing: boolean,\n reads: readonly string[] = [],\n own = LEGACY.scoopRoot(record.folder)\n): boolean {\n const write = [own, '/tmp', ...(record.roots?.write ?? [])];\n const roots = writing ? write : [...write, coneCwd, ...(record.roots?.read ?? []), ...reads];\n return roots.some((root) => path === root || path.startsWith(`${root === '/' ? '' : root}/`));\n}\n\nexport function guardExtension(lookup: Lookup): Extension {\n return defineExtension({\n name: 'slicc-scoop-guard',\n hooks: [\n hook(ToolTask, {\n async beforeTool(call, api, context) {\n if (call.name !== 'read' && !WRITES.has(call.name)) return undefined;\n const { agents, reads, layout = LEGACY, enforced, envOf } = await lookup();\n const record = Object.values(agents.state().scoops).find(\n (scoop) => scoop.conversation === api.conversationId\n );\n if (!record || enforced) return undefined;\n const own = layout.scoopRoot(record.folder);\n const cone = layout.users ? own : HOME;\n const path = String(call.arguments.path);\n const asked = normalize(resolve(layout.workspace(record.folder), path));\n const env = await envOf?.(api.conversationId, context);\n const canonical = await env?.canonicalPath(asked, context);\n const target = canonical?.ok ? canonical.value : asked;\n const writing = WRITES.has(call.name);\n const skills = reads?.() ?? [];\n if (\n allowed(record, cone, target, writing, skills, own) ||\n allowed(record, cone, asked, writing, skills, own)\n )\n return undefined;\n const reach = layout.users || writing ? '' : `, and reads ${HOME}`;\n return {\n block: `${target} is outside this scoop's folders. ${call.name} reaches ${own} and /tmp${reach}.`,\n };\n },\n }),\n ],\n });\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import type { Context } from '@earendil-works/chord';\nimport {\n AssistantEntry,\n type ConversationId,\n defineExtension,\n defineTask,\n type Extension,\n hook,\n type PromptInput,\n type Submission,\n section,\n ToolTask,\n type Tx,\n} from '@earendil-works/pi-durable';\nimport { answerText } from '../agent.ts';\nimport { AgentsDoc, type AgentsState, live, type ScoopRecord } from '../agents.ts';\nimport { distinctTaints, type InheritedTaint, runTaints } from '../guests/guard.ts';\nimport { HOME } from '../kernel/env.ts';\nimport { normalize, resolve } from '../kernel/paths.ts';\nimport { type Layout, LEGACY } from '../layout.ts';\nimport type { LickEvent } from '../licks/licks.ts';\nimport { pauseUntil } from '../pause.ts';\nimport { FROM_KIND } from './from.ts';\nimport { type Feed, type ScoopsHost, ScoopWorkDoc } from './service.ts';\nimport { cardOf } from './summary.ts';\n\nexport const PREVIEW = 1000;\n\ntype Lookup = () => Promise<ScoopsHost>;\n\nexport async function scoopTainted(\n host: Pick<ScoopsHost, 'harness'>,\n state: Readonly<AgentsState>,\n scoops: readonly string[],\n event: LickEvent,\n context: Context,\n extra: readonly InheritedTaint[] = []\n): Promise<LickEvent> {\n const found: InheritedTaint[] = [...extra];\n for (const id of scoops) {\n const conversation = state.scoops[id]?.conversation;\n if (conversation !== undefined)\n found.push(...(await runTaints(host.harness, conversation as ConversationId, context)));\n }\n const taints = distinctTaints(found);\n return taints.length ? { ...event, taints } : event;\n}\n\nexport function scoopFacts(\n record: Pick<ScoopRecord, 'name' | 'folder' | 'role'> & { cone?: string },\n layout: Layout = LEGACY\n): string {\n const place = layout.workspace(record.folder);\n return [\n `You are the scoop \"${record.name}\"${record.role ? ` (role: ${record.role})` : ''}, a helper agent working for a cone. Messages come from the cone or from the user at a terminal; your final answer goes back to whoever asked, so end every task with a complete answer.`,\n layout.users\n ? `You run as the user ${layout.scoopRoot(record.folder).slice('/home/'.length)}, and your home is ${place}: work there. Your cone can read your home; you can't read your cone's home or another scoop's. /tmp is shared scratch.`\n : `Work in ${place}. Your read, write and edit tools only reach ${layout.scoopRoot(record.folder)} and /tmp, and read ${HOME}.`,\n layout.users\n ? 'Your bash runs as your user too, so the kernel decides what it may read and change. Stay in your home, and change nothing outside it unless the request says so.'\n : 'Your bash is not confined: it sees the whole file system and every process. Stay in your folder anyway, and change nothing outside it unless the request says so.',\n 'You may run `agent` synchronously for a bounded side task (calls nest at most three deep), but you cannot start asynchronous scoops (`agent --async`, `subagent spawn`).',\n ].join('\\n');\n}\n\nfunction lines(text: string): number {\n return text ? text.split('\\n').length : 0;\n}\n\nexport type ReportResult = { text: string; failed: string | null; path: string | null };\n\nexport function reportLick(\n record: ScoopRecord,\n id: string,\n report: ReportResult,\n route: { target?: string | null; channel?: 'scoop-notify' | 'bash' } = {}\n): LickEvent {\n const status = report.failed ? (report.failed === 'aborted' ? 'stopped' : 'failed') : 'completed';\n const label = `${record.name} (${record.role ?? 'scoop'})`;\n const preview = report.text.length > PREVIEW ? `${report.text.slice(0, PREVIEW)}\u2026` : report.text;\n const where = report.path ? `Output: ${report.path} (${lines(report.text)} lines)` : null;\n const reason = report.failed && report.failed !== 'aborted' ? `Reason: ${report.failed}` : null;\n return {\n channel: route.channel ?? 'scoop-notify',\n source: id,\n title: label,\n text: `[scoop ${record.name} (${record.role ?? 'scoop'}) ${status}]`,\n body: [where, reason, preview].filter(Boolean).join('\\n\\n'),\n target: (route.target ?? `cone:${record.cone}`) as LickEvent['target'],\n ...cardOf(record.name, report),\n ...(report.failed && report.failed !== 'aborted' ? { severity: 'warn' as const } : {}),\n };\n}\n\ntype Noting = {\n commit: (\n write: (\n tx: Tx\n ) => Promise<{ status: 'running'; checkpoint: { phase: 'deliver'; noted: true } }>,\n context: Context\n ) => Promise<unknown>;\n};\n\nexport async function noteWhenPlaced(\n runtime: Noting,\n submission: Pick<Submission, 'status'>,\n conversation: ConversationId,\n note: { from: string | undefined; agent?: boolean; noted: boolean | undefined },\n context: Context\n): Promise<void> {\n const { from } = note;\n while (from && !note.noted && !context.abortSignal?.aborted) {\n const record = await submission.status(context);\n if (record.status !== 'queued') {\n if (!('entry' in record) || record.entry === undefined) return;\n const entry = record.entry;\n await runtime\n .commit(async (tx) => {\n await tx.appendEntry(conversation, {\n kind: FROM_KIND,\n data: { from, entry, ...(note.agent ? { agent: true } : {}) },\n });\n return { status: 'running', checkpoint: { phase: 'deliver', noted: true } };\n }, context)\n .catch(() => undefined);\n return;\n }\n await new Promise((done) => setTimeout(done, NOTE_POLL_MS));\n }\n}\n\nexport const NOTE_POLL_MS = 100;\n\nexport function waitTask(lookup: Lookup) {\n type WaitInput = {\n scoops: string[];\n cone: string;\n deadline: number;\n taints?: InheritedTaint[];\n };\n\n return defineTask<WaitInput, { phase: 'start' } | { phase: 'watch' }, null>({\n name: 'slicc.scoop-wait',\n version: 1,\n initial: () => ({ phase: 'start' }),\n phases: {\n async start(task, runtime, context) {\n await runtime.commit(async (tx) => {\n (await tx.doc(ScoopWorkDoc)).waits[String(task.id)] = {\n scoops: task.input.scoops,\n done: {},\n cone: task.input.cone,\n };\n return { status: 'running', checkpoint: { phase: 'watch' } };\n }, context);\n },\n async watch(task, runtime, context) {\n const host = await lookup();\n const { agents, licks } = host;\n const key = String(task.id);\n for (;;) {\n const work = await runtime.snapshot(ScoopWorkDoc, context);\n const state = work?.waits[key];\n if (!state) break;\n const feeding = new Set(Object.values(work?.feeds ?? {}).map((feed) => feed.scoop));\n const open = state.scoops.filter((id) => !(id in state.done) && feeding.has(id));\n const expired = runtime.now() >= task.input.deadline;\n if (open.length && !expired) {\n await pauseUntil(runtime, Math.min(runtime.now() + 300, task.input.deadline), context);\n continue;\n }\n const names = (id: string) => agents.state().scoops[id]?.name ?? id;\n const body = state.scoops.map((id) =>\n open.includes(id)\n ? `## ${names(id)}\\n(still working when the wait timed out)`\n : `## ${names(id)}\\n${state.done[id] ?? '(nothing was running)'}`\n );\n const lick: LickEvent = {\n channel: 'scoop-wait',\n source: key,\n title: `Waited for ${state.scoops.map(names).join(', ')}`,\n text: open.length\n ? `${state.scoops.length - open.length} of ${state.scoops.length} done; timed out waiting for ${open.map(names).join(', ')}`\n : `All ${state.scoops.length} done`,\n body: body.join('\\n\\n'),\n target: `cone:${state.cone}`,\n coalesce: false,\n eventId: `wait:${key}`,\n };\n await licks.deliver(\n await scoopTainted(\n host,\n agents.state(),\n state.scoops,\n lick,\n context,\n task.input.taints\n ),\n context\n );\n break;\n }\n await runtime.commit(async (tx) => {\n delete (await tx.doc(ScoopWorkDoc)).waits[key];\n return { status: 'terminal', outcome: { status: 'completed', result: null } };\n }, context);\n },\n },\n abort: (task, runtime, context) =>\n runtime.commit(async (tx) => {\n delete (await tx.doc(ScoopWorkDoc)).waits[String(task.id)];\n return { status: 'terminal', outcome: { status: 'aborted' } };\n }, context),\n });\n}\n\nexport function scoopTasks(lookup: Lookup) {\n const anchor = defineTask<null, { phase: 'done' }, null>({\n name: 'slicc.scoop-anchor',\n version: 1,\n initial: () => ({ phase: 'done' }),\n phases: {\n done: (_task, runtime, context) =>\n runtime.commit(\n () => ({ status: 'terminal', outcome: { status: 'completed', result: null } }),\n context\n ),\n },\n abort: (_task, runtime, context) =>\n runtime.commit(() => ({ status: 'terminal', outcome: { status: 'aborted' } }), context),\n });\n\n type ReporterInput = {\n scoop: string;\n prompt: string;\n followUp?: boolean;\n request?: string;\n };\n type ReporterState =\n | { phase: 'deliver'; noted?: boolean }\n | { phase: 'report'; text: string; failed: string | null };\n\n const reporter = defineTask<ReporterInput, ReporterState, ReportResult>({\n name: 'slicc.scoop-reporter',\n version: 1,\n initial: () => ({ phase: 'deliver' }),\n phases: {\n async deliver(task, runtime, context) {\n const { agents } = await lookup();\n const record = agents.state().scoops[task.input.scoop];\n const handle =\n record && live(record)\n ? await runtime.conversation(record.conversation as ConversationId, context)\n : undefined;\n if (!handle) {\n await runtime.commit(async (tx) => {\n delete (await tx.doc(ScoopWorkDoc)).feeds[String(task.id)];\n return {\n status: 'terminal',\n outcome: {\n status: 'completed',\n result: { text: '', failed: 'the scoop is gone', path: null },\n },\n };\n }, context);\n return;\n }\n const requestId = task.input.request ? `subagent:${task.input.request}` : `feed:${task.id}`;\n const feed = (await runtime.snapshot(ScoopWorkDoc, context))?.feeds[String(task.id)];\n const submission = await handle.submit(\n {\n type: 'input',\n content: task.input.prompt,\n whenBusy: task.input.followUp ? 'followUp' : 'steer',\n requestId,\n },\n context\n );\n const noting = noteWhenPlaced(\n runtime,\n submission,\n record?.conversation as ConversationId,\n { from: feed?.from, agent: feed?.agent === true, noted: task.state.checkpoint.noted },\n context\n );\n const settled = await submission.wait(context);\n await noting;\n await runtime.commit(async (tx) => {\n if (settled.status !== 'done' || settled.type !== 'input')\n return {\n status: 'running',\n checkpoint: {\n phase: 'report',\n text: '',\n failed: String(settled.reason),\n },\n };\n const answer = await tx.entry(AssistantEntry, settled.answer);\n return {\n status: 'running',\n checkpoint: {\n phase: 'report',\n text: answerText(answer?.model?.[0]?.content),\n failed: null,\n },\n };\n }, context);\n },\n async report(task, runtime, context) {\n const host = await lookup();\n const { agents, licks, layout = LEGACY } = host;\n const id = task.input.scoop;\n const record = agents.state().scoops[id];\n const { text, failed } = task.state.checkpoint;\n const path =\n record && text ? `${layout.reports(record.folder, record.cone)}/${task.id}.md` : null;\n if (path)\n await (await runtime.env(context))?.writeFile(\n path,\n text.endsWith('\\n') ? text : `${text}\\n`,\n context\n );\n const work = await runtime.snapshot(ScoopWorkDoc, context);\n const entry = work?.feeds[String(task.id)] as Feed;\n const waiting = (wait: { scoops: string[]; done: Record<string, string> }) =>\n wait.scoops.includes(id) && !(id in wait.done);\n const folded = Object.values(work?.waits ?? {}).some(waiting);\n const route = { target: entry.target, channel: entry.channel };\n if (!folded && record && entry.report && failed !== 'aborted')\n await licks.deliver(\n await scoopTainted(\n host,\n agents.state(),\n [id],\n {\n ...reportLick(record, id, { text, failed, path }, route),\n eventId: `report:${task.id}`,\n },\n context\n ),\n context\n );\n await runtime.commit(async (tx) => {\n const work = await tx.doc(ScoopWorkDoc);\n for (const wait of Object.values(work.waits))\n if (waiting(wait))\n wait.done[id] = failed\n ? `stopped: ${failed}`\n : `${path ? `Output: ${path}\\n` : ''}${text || '(no text)'}`;\n delete work.feeds[String(task.id)];\n return {\n status: 'terminal',\n outcome: { status: 'completed', result: { text, failed, path } },\n };\n }, context);\n },\n },\n abort: (task, runtime, context) =>\n runtime.commit(async (tx) => {\n delete (await tx.doc(ScoopWorkDoc)).feeds[String(task.id)];\n return { status: 'terminal', outcome: { status: 'aborted' } };\n }, context),\n });\n\n return { anchor, reporter, wait: waitTask(lookup) };\n}\n\nasync function whose(input: PromptInput, context: Context) {\n const state = await input.read.snapshot(AgentsDoc, context);\n const scoop = Object.values(state?.scoops ?? {}).find(\n (record) => record.conversation === input.conversationId\n );\n return { scoop };\n}\n\nexport function scoopsExtension(\n tasks: ReturnType<typeof scoopTasks>,\n layout: () => Layout = () => LEGACY\n): Extension {\n return defineExtension({\n name: 'slicc-scoops',\n tasks: [tasks.anchor, tasks.reporter, tasks.wait],\n sections: [\n section('scoop', async (input, context) => {\n const { scoop } = await whose(input, context);\n return scoop ? scoopFacts(scoop, layout()) : undefined;\n }),\n ],\n });\n}\n\nconst WRITES = new Set(['write', 'edit']);\n\nexport function allowed(\n record: Pick<ScoopRecord, 'folder'> & { roots?: ScoopRecord['roots'] },\n coneCwd: string,\n path: string,\n writing: boolean,\n reads: readonly string[] = [],\n own = LEGACY.scoopRoot(record.folder)\n): boolean {\n const write = [own, '/tmp', ...(record.roots?.write ?? [])];\n const roots = writing ? write : [...write, coneCwd, ...(record.roots?.read ?? []), ...reads];\n return roots.some((root) => path === root || path.startsWith(`${root === '/' ? '' : root}/`));\n}\n\nexport function guardExtension(lookup: Lookup): Extension {\n return defineExtension({\n name: 'slicc-scoop-guard',\n hooks: [\n hook(ToolTask, {\n async beforeTool(call, api, context) {\n if (call.name !== 'read' && !WRITES.has(call.name)) return undefined;\n const { agents, reads, layout = LEGACY, enforced, envOf } = await lookup();\n const record = Object.values(agents.state().scoops).find(\n (scoop) => scoop.conversation === api.conversationId\n );\n if (!record || enforced) return undefined;\n const own = layout.scoopRoot(record.folder);\n const cone = layout.users ? own : HOME;\n const path = String(call.arguments.path);\n const asked = normalize(resolve(layout.workspace(record.folder), path));\n const env = await envOf?.(api.conversationId, context);\n const canonical = await env?.canonicalPath(asked, context);\n const target = canonical?.ok ? canonical.value : asked;\n const writing = WRITES.has(call.name);\n const skills = reads?.() ?? [];\n if (\n allowed(record, cone, target, writing, skills, own) ||\n allowed(record, cone, asked, writing, skills, own)\n )\n return undefined;\n const reach = layout.users || writing ? '' : `, and reads ${HOME}`;\n return {\n block: `${target} is outside this scoop's folders. ${call.name} reaches ${own} and /tmp${reach}.`,\n };\n },\n }),\n ],\n });\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["work"]
7
7
  }
@@ -7,6 +7,7 @@ import {
7
7
  live,
8
8
  scoopId
9
9
  } from "../agents.js";
10
+ import { deltasOnly } from "../checkpoints.js";
10
11
  import { CODEMODE } from "../codemode/index.js";
11
12
  import { distinctTaints, GuestTaintDoc } from "../guests/guard.js";
12
13
  import { LEGACY } from "../layout.js";
@@ -16,6 +17,7 @@ import { SCOOPS_ROOT } from "../layout.js";
16
17
  const LEDGER_SIZE = 512;
17
18
  const ScoopWorkDoc = defineDoc({
18
19
  kind: "slicc.scoops.work",
20
+ checkpointWhen: deltasOnly,
19
21
  version: 1,
20
22
  scope: "session",
21
23
  initial: () => ({ feeds: {}, waits: {}, ledger: {}, turns: {} })
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/scoops/service.ts"],
4
- "sourcesContent": ["import type { Context } from '@earendil-works/chord';\nimport {\n type AgentChange,\n type AnyTask,\n type Conversation,\n type ConversationId,\n configure,\n defineDoc,\n type Extension,\n type Harness,\n type TaskId,\n type ToolRegistration,\n type Tx,\n} from '@earendil-works/pi-durable';\nimport type { ExecutionEnv } from '@earendil-works/pi-durable/env';\nimport {\n type Agents,\n type AgentsState,\n freeFolder,\n live,\n type Mark,\n type ScoopRecord,\n scoopId,\n} from '../agents.ts';\nimport { CODEMODE } from '../codemode/index.ts';\nimport { distinctTaints, GuestTaintDoc, type InheritedTaint } from '../guests/guard.ts';\nimport type { ProcessGroups } from '../kernel/groups.ts';\nimport { type Layout, LEGACY } from '../layout.ts';\nimport type { Licks } from '../licks/licks.ts';\nimport { McpAllowDoc, mcpEntries } from '../mcp/index.ts';\nimport type { Role } from '../roles/roles.ts';\nimport type { Choosable } from '../selection.ts';\nimport { visible } from './visible.ts';\n\nexport { SCOOPS_ROOT } from '../layout.ts';\nexport const LEDGER_SIZE = 512;\n\nexport type Feed = {\n scoop: string;\n created: Mark | null;\n report: boolean;\n target: string | null;\n channel: 'scoop-notify' | 'bash';\n from?: string;\n agent?: boolean;\n};\ntype Wait = { scoops: string[]; done: Record<string, string>; cone: string };\nexport type Answer = { code: number; out: string; err?: string; tasks?: number[] };\ntype WorkState = {\n feeds: Record<string, Feed>;\n waits: Record<string, Wait>;\n ledger: Record<string, Answer>;\n turns: Record<string, { at: number; count: number }>;\n};\n\nexport const ScoopWorkDoc = defineDoc<WorkState>({\n kind: 'slicc.scoops.work',\n version: 1,\n scope: 'session',\n initial: () => ({ feeds: {}, waits: {}, ledger: {}, turns: {} }),\n});\n\nexport interface ScoopTasks {\n anchor: AnyTask;\n reporter: AnyTask;\n wait: AnyTask;\n}\n\nexport type EnvOf = (\n conversationId: ConversationId,\n context: Context\n) => Promise<Pick<ExecutionEnv, 'canonicalPath'> | undefined>;\n\nexport interface ScoopsHost {\n harness: Harness;\n agents: Agents;\n licks: Licks;\n groups?: ProcessGroups;\n tools?: readonly ToolRegistration[];\n reads?: () => readonly string[];\n files?: Pick<ExecutionEnv, 'remove' | 'createDir'>;\n envOf?: EnvOf;\n mcp?: (names: readonly string[]) => ToolRegistration[];\n layout?: Layout;\n enforced?: boolean;\n exclude?: readonly Extension[];\n}\n\nexport interface Rewound {\n stopped: string[];\n restored: string[];\n}\n\nexport interface ScoopSummary {\n id: string;\n folder: string;\n name: string;\n role: string | null;\n busy: boolean;\n}\n\nexport interface Limits {\n maxLiveScoops: number;\n maxPerTurn: number;\n}\n\nexport interface SpawnRequest {\n cone: string;\n kind?: 'async' | 'sync';\n parent?: string;\n depth?: number;\n roots?: { write: string[]; read: string[] };\n cwd?: string;\n origin?: string;\n instructions?: string;\n target?: string | null;\n asker?: string | null;\n name: string;\n role?: Role;\n model?: { provider: string; modelId: string };\n thinking?: AgentChange['thinkingLevel'];\n tools?: string[];\n prompts: string[];\n fromAgent: boolean;\n request?: string;\n limits: Limits;\n taints?: InheritedTaint[];\n created?: (tx: Tx, made: Spawned) => Promise<void>;\n}\n\nexport interface FeedOptions {\n fromAgent: boolean;\n request: string;\n followUp: boolean;\n target: string | null;\n taints?: InheritedTaint[];\n}\n\nexport interface Spawned {\n folder: string;\n conversation: number;\n tasks: number[];\n}\n\nexport function workspace(folder: string, layout: Layout = LEGACY): string {\n return layout.workspace(folder);\n}\n\nexport async function tail(conversation: Conversation, context: Context): Promise<Mark> {\n const { entries } = await conversation.context(context);\n return { in: conversation.id, at: Number(entries.at(-1)?.id ?? 0) };\n}\n\nexport async function turnStart(conversation: Conversation, context: Context): Promise<number> {\n const { entries } = await conversation.context(context);\n return Number(entries.findLast((entry) => entry.kind === 'pi.user')?.id ?? 0);\n}\n\nexport function coneOf(state: Readonly<AgentsState>, conversation: number): string | undefined {\n return Object.entries(state.cones).find(([, cone]) => cone.conversation === conversation)?.[0];\n}\n\nexport function findScoop(\n state: Readonly<AgentsState>,\n handle: string,\n cone: string | null\n): [string, ScoopRecord] | undefined {\n const id = handle.startsWith('scoop:') ? handle : scoopId(handle);\n const reachable = (record: ScoopRecord | undefined): record is ScoopRecord =>\n !!record && live(record) && (cone === null || record.cone === cone);\n const record = state.scoops[id];\n if (reachable(record)) return [id, record];\n return Object.entries(state.scoops).find(\n ([, candidate]) => reachable(candidate) && candidate.name === handle\n );\n}\n\nfunction remember(work: WorkState, request: string | undefined, answer: Answer): void {\n if (!request) return;\n work.ledger[request] = answer;\n const keys = Object.keys(work.ledger);\n for (const key of keys.slice(0, Math.max(0, keys.length - LEDGER_SIZE))) delete work.ledger[key];\n}\n\ntype Core = { host: Promise<ScoopsHost>; tasks: () => ScoopTasks };\n\nasync function coneOfId(core: Core, coneId: string, context: Context): Promise<Conversation> {\n const { agents } = await core.host;\n const found = await agents.conversation(coneId, context);\n if (!found) throw new Error(`There is no cone ${coneId}.`);\n return found;\n}\n\nasync function isBusy(core: Core, conversation: number, context: Context): Promise<boolean> {\n const { harness } = await core.host;\n const handle = await harness.conversation(conversation as ConversationId, context);\n const view = await handle?.viewState(context);\n const run = (view?.value.docs['pi.live'] as { run?: unknown } | undefined)?.run;\n view?.dispose();\n return Boolean(run);\n}\n\nasync function answered(\n core: Core,\n request: string | undefined,\n context: Context\n): Promise<Answer | undefined> {\n if (!request) return undefined;\n const { harness } = await core.host;\n return (await harness.snapshot(ScoopWorkDoc, context))?.ledger[request];\n}\n\ntype NewFeed = Omit<Feed, 'channel' | 'from'> & {\n from: string;\n agent: boolean;\n prompt: string;\n request?: string;\n followUp?: boolean;\n};\n\nasync function addFeed(core: Core, tx: Tx, parent: number, feed: NewFeed): Promise<number> {\n const task = await tx.createTask(\n core.tasks().reporter as never,\n {\n scoop: feed.scoop,\n prompt: feed.prompt,\n ...(feed.followUp ? { followUp: true } : {}),\n ...(feed.request ? { request: feed.request } : {}),\n },\n {\n ownership: { kind: 'conversation' },\n conversationId: parent as ConversationId,\n background: true,\n }\n );\n (await tx.doc(ScoopWorkDoc)).feeds[String(task)] = {\n scoop: feed.scoop,\n created: feed.created,\n report: feed.report,\n target: feed.target,\n channel: 'scoop-notify',\n from: feed.from,\n agent: feed.agent,\n };\n return Number(task);\n}\n\nexport function choosable(tools: readonly ToolRegistration[]): Choosable {\n const names = new Set(tools.map((tool) => tool.name));\n return (name) => names.has(name) || (mcpEntries([name]) ?? []).length > 0;\n}\n\nfunction selection(\n tools: readonly ToolRegistration[] | undefined,\n names: string[] | undefined,\n mcp?: (names: readonly string[]) => ToolRegistration[]\n) {\n if (!names || !tools) return undefined;\n const picked = tools.filter((tool) => names.includes(tool.name));\n const entries = mcpEntries(names) ?? [];\n if (!entries.length) return picked;\n const codemode = tools.find((tool) => tool.name === CODEMODE);\n if (codemode && !picked.includes(codemode)) picked.push(codemode);\n return [...picked, ...(mcp?.(entries) ?? [])];\n}\n\nfunction liveCount(state: Readonly<AgentsState>, cone: string): number {\n return Object.values(state.scoops).filter((scoop) => scoop.cone === cone && live(scoop)).length;\n}\n\nfunction claimTurn(\n work: WorkState,\n request: SpawnRequest,\n turn: number | null\n): Answer | undefined {\n if (turn === null) return undefined;\n const counted = work.turns[request.cone];\n const count = counted && counted.at === turn ? counted.count : 0;\n if (count >= request.limits.maxPerTurn)\n return {\n code: 1,\n out: `subagent: this turn already started ${count} scoops (the limit is ${request.limits.maxPerTurn})\\n`,\n };\n work.turns[request.cone] = { at: turn, count: count + 1 };\n return undefined;\n}\n\nexport function agentChange(\n request: SpawnRequest,\n folder: string,\n host: Pick<ScoopsHost, 'tools' | 'mcp' | 'layout' | 'exclude'>\n): AgentChange {\n const { tools, mcp } = host;\n const model = request.model ?? modelOf(request.role?.model);\n const thinking = request.thinking ?? request.role?.thinking;\n const chosen = selection(tools, request.tools ?? request.role?.tools, mcp);\n const instructions = [request.role?.prompt, request.instructions].filter(Boolean).join('\\n\\n');\n return {\n cwd: request.cwd ?? workspace(folder, host.layout),\n ...(instructions ? { instructions } : {}),\n ...(model ? { model } : {}),\n ...(thinking ? { thinkingLevel: thinking as AgentChange['thinkingLevel'] } : {}),\n ...(chosen ? { tools: chosen } : {}),\n ...(host.exclude?.length ? { extensions: { remove: host.exclude } } : {}),\n };\n}\n\nasync function narrowMcp(\n tx: Tx,\n state: Readonly<AgentsState>,\n cone: ConversationId,\n child: ConversationId,\n request: SpawnRequest\n): Promise<void> {\n const listed = mcpEntries(request.tools ?? request.role?.tools);\n const caller = state.scoops[request.parent ?? '']?.conversation as ConversationId | undefined;\n const inherited = (await tx.doc(McpAllowDoc, caller ?? cone)).allow;\n if (listed !== null || inherited !== null)\n (await tx.doc(McpAllowDoc, child)).allow = listed ?? inherited;\n}\n\nfunction scoopRecord(\n request: SpawnRequest,\n folder: string,\n conversation: number,\n anchor: number,\n created: Mark | null\n): ScoopRecord {\n return {\n name: request.name.trim() || folder,\n folder,\n cone: request.cone,\n conversation,\n anchor,\n role: request.role?.name ?? null,\n ...(request.role?.memory ? { memory: request.role.memory } : {}),\n ...(request.role?.memory && request.origin ? { origin: request.origin } : {}),\n ...(request.role?.context ? { context: request.role.context } : {}),\n kind: request.kind ?? 'async',\n parent: request.parent ?? request.cone,\n depth: request.depth ?? 1,\n roots: request.roots ?? null,\n created,\n dropped: null,\n gone: false,\n };\n}\n\nasync function spawn(core: Core, request: SpawnRequest, context: Context): Promise<Answer> {\n const done = await answered(core, request.request, context);\n if (done) return done;\n const host = await core.host;\n const { agents } = host;\n const parent = await coneOfId(core, request.cone, context);\n const count = liveCount(agents.state(), request.cone);\n if (count >= request.limits.maxLiveScoops)\n return {\n code: 1,\n out: `subagent: this cone already has ${count} live scoops (the limit is ${request.limits.maxLiveScoops}); stop one first\\n`,\n };\n const created = request.fromAgent ? await tail(parent, context) : null;\n const turn = request.fromAgent ? await turnStart(parent, context) : null;\n return agents.update(async (tx, doc) => {\n const work = await tx.doc(ScoopWorkDoc);\n const refused = claimTurn(work as WorkState, request, turn);\n if (refused) return refused;\n const folder = freeFolder(doc, request.name);\n const id = scoopId(folder);\n const anchor = await tx.createTask(core.tasks().anchor as never, null, {\n ownership: { kind: 'conversation' },\n conversationId: parent.id,\n background: true,\n });\n const child = await tx.createConversation({ ownership: { kind: 'task', taskId: anchor } });\n await configure(tx, child.id, agentChange(request, folder, host));\n await narrowMcp(tx, doc, parent.id, child.id, request);\n if (request.taints?.length) (await tx.doc(GuestTaintDoc, child.id)).taints = request.taints;\n doc.scoops[id] = scoopRecord(request, folder, child.id, Number(anchor), created);\n const target =\n request.target === undefined\n ? request.fromAgent\n ? `cone:${request.cone}`\n : null\n : request.target;\n const made: number[] = [];\n const asker = request.asker === undefined ? target : request.asker;\n const from = askerName(doc, asker);\n for (const prompt of request.prompts)\n made.push(\n await addFeed(core, tx, parent.id, {\n scoop: id,\n created,\n report: target !== null,\n target,\n from,\n agent: asker !== null,\n prompt,\n })\n );\n const answer = { code: 0, out: `${folder}\\n`, tasks: made };\n await request.created?.(tx, { folder, conversation: Number(child.id), tasks: made });\n remember(work as WorkState, request.request, answer);\n return answer;\n }, context);\n}\n\nexport function askerName(state: Readonly<AgentsState>, asker: string | null): string {\n if (asker === null) return 'terminal';\n if (asker.startsWith('cone:')) return state.cones[asker.slice('cone:'.length)]?.name ?? asker;\n return state.scoops[asker]?.name ?? asker;\n}\n\nconst missing = (id: string): Answer => ({\n code: 1,\n out: `subagent: there is no scoop ${id.replace('scoop:', '')}\\n`,\n});\n\nasync function feed(\n core: Core,\n id: string,\n prompt: string,\n options: FeedOptions,\n context: Context\n): Promise<Answer> {\n const done = await answered(core, options.request, context);\n if (done) return done;\n const { harness, agents } = await core.host;\n const record = agents.state().scoops[id];\n if (!record || !live(record)) return missing(id);\n const parent = await coneOfId(core, record.cone, context);\n const created = options.fromAgent ? await tail(parent, context) : null;\n const { target } = options;\n return harness.commit(async (tx) => {\n if (options.taints?.length) {\n const doc = await tx.doc(GuestTaintDoc, record.conversation as ConversationId);\n doc.taints = distinctTaints([...doc.taints, ...options.taints]);\n }\n await addFeed(core, tx, parent.id, {\n scoop: id,\n created,\n report: target !== null,\n target,\n from: askerName(agents.state(), target),\n agent: target !== null,\n prompt,\n followUp: options.followUp,\n request: options.request,\n });\n const answer = { code: 0, out: `sent to ${record.folder}\\n` };\n remember((await tx.doc(ScoopWorkDoc)) as WorkState, options.request, answer);\n return answer;\n }, context);\n}\n\nasync function signal(core: Core, record: ScoopRecord, context: Context): Promise<void> {\n const { harness, groups } = await core.host;\n const conversation = await harness.conversation(record.conversation as ConversationId, context);\n await conversation?.abort(context, { background: true });\n await groups?.signal(record.conversation);\n}\n\nasync function stopFeeds(\n core: Core,\n scoop: string,\n keep: (feed: Feed) => Promise<boolean>,\n context: Context\n) {\n const { harness } = await core.host;\n const work = (await harness.snapshot(ScoopWorkDoc, context)) ?? { feeds: {} };\n const dropped: string[] = [];\n for (const [task, entry] of Object.entries(work.feeds)) {\n if (entry.scoop !== scoop || (await keep(entry))) continue;\n const record = await harness.getTask(Number(task) as TaskId, context);\n if (record && record.state.status !== 'terminal')\n await harness.abortTask(Number(task) as TaskId, context);\n dropped.push(task);\n }\n if (dropped.length)\n await harness.commit(async (tx) => {\n const doc = await tx.doc(ScoopWorkDoc);\n for (const task of dropped) delete doc.feeds[task];\n }, context);\n return dropped.length;\n}\n\nasync function stop(core: Core, id: string, fromAgent: boolean, context: Context): Promise<Answer> {\n const { agents, files, layout = LEGACY } = await core.host;\n const record = agents.state().scoops[id];\n if (!record || !live(record)) return missing(id);\n await stopFeeds(core, id, async () => false, context);\n await signal(core, record, context);\n const mark = fromAgent\n ? await tail(await coneOfId(core, record.cone, context), context)\n : { in: 0, at: 0 };\n await agents.update((_tx, state) => {\n (state.scoops[id] as ScoopRecord).dropped = mark;\n }, context);\n const place = layout.workspace(record.folder);\n const removed = await files?.remove(place, { recursive: true, force: true }, context);\n const folder = removed?.ok ? `removed ${place}` : `kept ${place}`;\n return {\n code: 0,\n out: `stopped ${record.folder}; its transcript is kept, ${folder}, and its reports stay in ${layout.reports(record.folder, record.cone)}\\n`,\n };\n}\n\nasync function rename(core: Core, id: string, name: string, context: Context): Promise<Answer> {\n const { agents } = await core.host;\n const record = agents.state().scoops[id];\n if (!record || !live(record)) return missing(id);\n const wanted = name.trim();\n if (!wanted) return { code: 2, out: 'subagent: rename needs a non-empty name\\n' };\n await agents.update((_tx, state) => {\n (state.scoops[id] as ScoopRecord).name = wanted;\n }, context);\n return { code: 0, out: `${record.folder} is now called ${wanted}\\n` };\n}\n\nasync function resetWorkspace(\n host: Pick<ScoopsHost, 'files' | 'layout'>,\n folder: string,\n context: Context\n): Promise<boolean> {\n const { files } = host;\n if (!files) return true;\n const place = workspace(folder, host.layout);\n const cleared = await files.remove(place, { recursive: true, force: true }, context);\n if (!cleared.ok) return false;\n if (host.layout?.users) return true;\n return (await files.createDir(place, { recursive: true }, context)).ok;\n}\n\ntype Seen = (mark: Mark | null) => Promise<boolean>;\n\nasync function rewindOne(\n core: Core,\n coneId: string,\n id: string,\n record: ScoopRecord,\n seen: Seen,\n result: Rewound,\n context: Context\n): Promise<Partial<ScoopRecord> | undefined> {\n const host = await core.host;\n const { harness, licks } = host;\n if (!(await seen(record.created))) {\n if (live(record)) {\n await stopFeeds(core, id, async () => false, context);\n await signal(core, record, context);\n result.stopped.push(record.name);\n }\n return { gone: true };\n }\n if (record.dropped !== null) {\n if (await seen(record.dropped)) return undefined;\n const reset = await resetWorkspace(host, record.folder, context);\n result.restored.push(\n reset ? record.name : `${record.name} (its working folder could not be reset)`\n );\n return { dropped: null };\n }\n const withdrawn = await stopFeeds(core, id, (entry) => seen(entry.created), context);\n if (!withdrawn) return undefined;\n const conversation = await harness.conversation(record.conversation as ConversationId, context);\n await conversation?.abort(context);\n await licks.forget(`cone:${coneId}`, 'scoop-notify', id, context);\n return undefined;\n}\n\nasync function rewound(\n core: Core,\n coneId: string,\n fork: Conversation,\n context: Context\n): Promise<Rewound> {\n const { harness, agents } = await core.host;\n const read = (id: number) =>\n harness.commit((tx) => tx.conversation(id as ConversationId), context);\n const seen: Seen = async (mark) =>\n mark === null || mark.in === 0 || (await visible(read, fork.id, mark));\n const result: Rewound = { stopped: [], restored: [] };\n const changes: [string, Partial<ScoopRecord>][] = [];\n for (const [id, record] of Object.entries(agents.state().scoops)) {\n if (record.cone !== coneId || record.gone) continue;\n const change = await rewindOne(core, coneId, id, record, seen, result, context);\n if (change) changes.push([id, change]);\n }\n if (changes.length)\n await agents.update((_tx, state) => {\n for (const [id, change] of changes) Object.assign(state.scoops[id] as ScoopRecord, change);\n }, context);\n return result;\n}\n\nasync function list(core: Core, coneId: string | null, context: Context): Promise<ScoopSummary[]> {\n const { agents } = await core.host;\n const out: ScoopSummary[] = [];\n for (const [id, record] of Object.entries(agents.state().scoops)) {\n if ((coneId !== null && record.cone !== coneId) || !live(record)) continue;\n out.push({\n id,\n folder: record.folder,\n name: record.name,\n role: record.role,\n busy: await isBusy(core, record.conversation, context),\n });\n }\n return out;\n}\n\nasync function working(core: Core, ids: readonly string[], context: Context): Promise<string[]> {\n const { harness, agents } = await core.host;\n const feeds = Object.values((await harness.snapshot(ScoopWorkDoc, context))?.feeds ?? {});\n const out: string[] = [];\n for (const id of ids) {\n const record = agents.state().scoops[id];\n if (!record) continue;\n if (\n feeds.some((entry) => entry.scoop === id) ||\n (await isBusy(core, record.conversation, context))\n )\n out.push(id);\n }\n return out;\n}\n\nasync function notifyWhenDone(\n core: Core,\n coneId: string,\n ids: string[],\n deadline: number,\n taints: readonly InheritedTaint[],\n context: Context\n) {\n const { harness } = await core.host;\n const parent = await coneOfId(core, coneId, context);\n await harness.commit(\n (tx) =>\n tx.createTask(\n core.tasks().wait as never,\n { scoops: ids, cone: coneId, deadline, ...(taints.length ? { taints } : {}) },\n { ownership: { kind: 'conversation' }, conversationId: parent.id, background: true }\n ),\n context\n );\n}\n\nasync function detach(core: Core, tasks: readonly number[], target: string, context: Context) {\n const { harness } = await core.host;\n await harness.commit(async (tx) => {\n const work = await tx.doc(ScoopWorkDoc);\n for (const task of tasks) {\n const entry = work.feeds[String(task)];\n if (!entry) continue;\n entry.report = true;\n entry.target = target;\n entry.channel = 'bash';\n }\n }, context);\n}\n\nasync function note(\n core: Core,\n id: string,\n text: string,\n taints: readonly InheritedTaint[],\n context: Context\n): Promise<Answer> {\n const { agents, licks } = await core.host;\n const record = agents.state().scoops[id];\n if (!record || !live(record)) return missing(id);\n const label = `${record.name} (${record.role ?? 'scoop'})`;\n await licks.deliver(\n {\n channel: 'scoop-notify',\n source: `${id}#note`,\n title: label,\n text: `[scoop ${label} progress]`,\n body: text,\n target: `cone:${record.cone}`,\n ...(taints.length ? { taints } : {}),\n },\n context\n );\n return { code: 0, out: 'note sent to the cone\\n' };\n}\n\nexport function createScoops(host: Promise<ScoopsHost>, tasks: () => ScoopTasks) {\n const core: Core = { host, tasks };\n return {\n detach: (made: readonly number[], target: string, context: Context) =>\n detach(core, made, target, context),\n note: (id: string, text: string, taints: readonly InheritedTaint[], context: Context) =>\n note(core, id, text, taints, context),\n lineage: async (pid: number | null) => (await core.host).groups?.lineage(pid),\n spawn: (request: SpawnRequest, context: Context) => spawn(core, request, context),\n feed: (id: string, prompt: string, options: FeedOptions, context: Context) =>\n feed(core, id, prompt, options, context),\n stop: (id: string, fromAgent: boolean, context: Context) => stop(core, id, fromAgent, context),\n rename: (id: string, name: string, context: Context) => rename(core, id, name, context),\n rewound: (coneId: string, fork: Conversation, context: Context) =>\n rewound(core, coneId, fork, context),\n list: (coneId: string | null, context: Context) => list(core, coneId, context),\n busy: (conversation: number, context: Context) => isBusy(core, conversation, context),\n working: (ids: readonly string[], context: Context) => working(core, ids, context),\n notifyWhenDone: (\n coneId: string,\n ids: string[],\n deadline: number,\n taints: readonly InheritedTaint[],\n context: Context\n ) => notifyWhenDone(core, coneId, ids, deadline, taints, context),\n };\n}\n\nexport function modelOf(\n value: string | undefined\n): { provider: string; modelId: string } | undefined {\n if (!value) return undefined;\n const at = value.indexOf('/');\n if (at <= 0) return undefined;\n return { provider: value.slice(0, at), modelId: value.slice(at + 1) };\n}\n\nexport type Scoops = ReturnType<typeof createScoops>;\n"],
5
- "mappings": "AACA;AAAA,EAKE;AAAA,EACA;AAAA,OAMK;AAEP;AAAA,EAGE;AAAA,EACA;AAAA,EAGA;AAAA,OACK;AACP,SAAS,gBAAgB;AACzB,SAAS,gBAAgB,qBAA0C;AAEnE,SAAsB,cAAc;AAEpC,SAAS,aAAa,kBAAkB;AAGxC,SAAS,eAAe;AAExB,SAAS,mBAAmB;AACrB,MAAM,cAAc;AAoBpB,MAAM,eAAe,UAAqB;AAAA,EAC/C,MAAM;AAAA,EACN,SAAS;AAAA,EACT,OAAO;AAAA,EACP,SAAS,OAAO,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,GAAG,QAAQ,CAAC,GAAG,OAAO,CAAC,EAAE;AAChE,CAAC;AAoFM,SAAS,UAAU,QAAgB,SAAiB,QAAgB;AACzE,SAAO,OAAO,UAAU,MAAM;AAChC;AAEA,eAAsB,KAAK,cAA4B,SAAiC;AACtF,QAAM,EAAE,QAAQ,IAAI,MAAM,aAAa,QAAQ,OAAO;AACtD,SAAO,EAAE,IAAI,aAAa,IAAI,IAAI,OAAO,QAAQ,GAAG,EAAE,GAAG,MAAM,CAAC,EAAE;AACpE;AAEA,eAAsB,UAAU,cAA4B,SAAmC;AAC7F,QAAM,EAAE,QAAQ,IAAI,MAAM,aAAa,QAAQ,OAAO;AACtD,SAAO,OAAO,QAAQ,SAAS,CAAC,UAAU,MAAM,SAAS,SAAS,GAAG,MAAM,CAAC;AAC9E;AAEO,SAAS,OAAO,OAA8B,cAA0C;AAC7F,SAAO,OAAO,QAAQ,MAAM,KAAK,EAAE,KAAK,CAAC,CAAC,EAAE,IAAI,MAAM,KAAK,iBAAiB,YAAY,IAAI,CAAC;AAC/F;AAEO,SAAS,UACd,OACA,QACA,MACmC;AACnC,QAAM,KAAK,OAAO,WAAW,QAAQ,IAAI,SAAS,QAAQ,MAAM;AAChE,QAAM,YAAY,CAACA,YACjB,CAAC,CAACA,WAAU,KAAKA,OAAM,MAAM,SAAS,QAAQA,QAAO,SAAS;AAChE,QAAM,SAAS,MAAM,OAAO,EAAE;AAC9B,MAAI,UAAU,MAAM,EAAG,QAAO,CAAC,IAAI,MAAM;AACzC,SAAO,OAAO,QAAQ,MAAM,MAAM,EAAE;AAAA,IAClC,CAAC,CAAC,EAAE,SAAS,MAAM,UAAU,SAAS,KAAK,UAAU,SAAS;AAAA,EAChE;AACF;AAEA,SAAS,SAAS,MAAiB,SAA6B,QAAsB;AACpF,MAAI,CAAC,QAAS;AACd,OAAK,OAAO,OAAO,IAAI;AACvB,QAAM,OAAO,OAAO,KAAK,KAAK,MAAM;AACpC,aAAW,OAAO,KAAK,MAAM,GAAG,KAAK,IAAI,GAAG,KAAK,SAAS,WAAW,CAAC,EAAG,QAAO,KAAK,OAAO,GAAG;AACjG;AAIA,eAAe,SAAS,MAAY,QAAgB,SAAyC;AAC3F,QAAM,EAAE,OAAO,IAAI,MAAM,KAAK;AAC9B,QAAM,QAAQ,MAAM,OAAO,aAAa,QAAQ,OAAO;AACvD,MAAI,CAAC,MAAO,OAAM,IAAI,MAAM,oBAAoB,MAAM,GAAG;AACzD,SAAO;AACT;AAEA,eAAe,OAAO,MAAY,cAAsB,SAAoC;AAC1F,QAAM,EAAE,QAAQ,IAAI,MAAM,KAAK;AAC/B,QAAM,SAAS,MAAM,QAAQ,aAAa,cAAgC,OAAO;AACjF,QAAM,OAAO,MAAM,QAAQ,UAAU,OAAO;AAC5C,QAAM,MAAO,MAAM,MAAM,KAAK,SAAS,GAAqC;AAC5E,QAAM,QAAQ;AACd,SAAO,QAAQ,GAAG;AACpB;AAEA,eAAe,SACb,MACA,SACA,SAC6B;AAC7B,MAAI,CAAC,QAAS,QAAO;AACrB,QAAM,EAAE,QAAQ,IAAI,MAAM,KAAK;AAC/B,UAAQ,MAAM,QAAQ,SAAS,cAAc,OAAO,IAAI,OAAO,OAAO;AACxE;AAUA,eAAe,QAAQ,MAAY,IAAQ,QAAgBC,OAAgC;AACzF,QAAM,OAAO,MAAM,GAAG;AAAA,IACpB,KAAK,MAAM,EAAE;AAAA,IACb;AAAA,MACE,OAAOA,MAAK;AAAA,MACZ,QAAQA,MAAK;AAAA,MACb,GAAIA,MAAK,WAAW,EAAE,UAAU,KAAK,IAAI,CAAC;AAAA,MAC1C,GAAIA,MAAK,UAAU,EAAE,SAASA,MAAK,QAAQ,IAAI,CAAC;AAAA,IAClD;AAAA,IACA;AAAA,MACE,WAAW,EAAE,MAAM,eAAe;AAAA,MAClC,gBAAgB;AAAA,MAChB,YAAY;AAAA,IACd;AAAA,EACF;AACA,GAAC,MAAM,GAAG,IAAI,YAAY,GAAG,MAAM,OAAO,IAAI,CAAC,IAAI;AAAA,IACjD,OAAOA,MAAK;AAAA,IACZ,SAASA,MAAK;AAAA,IACd,QAAQA,MAAK;AAAA,IACb,QAAQA,MAAK;AAAA,IACb,SAAS;AAAA,IACT,MAAMA,MAAK;AAAA,IACX,OAAOA,MAAK;AAAA,EACd;AACA,SAAO,OAAO,IAAI;AACpB;AAEO,SAAS,UAAU,OAA+C;AACvE,QAAM,QAAQ,IAAI,IAAI,MAAM,IAAI,CAAC,SAAS,KAAK,IAAI,CAAC;AACpD,SAAO,CAAC,SAAS,MAAM,IAAI,IAAI,MAAM,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,SAAS;AAC1E;AAEA,SAAS,UACP,OACA,OACA,KACA;AACA,MAAI,CAAC,SAAS,CAAC,MAAO,QAAO;AAC7B,QAAM,SAAS,MAAM,OAAO,CAAC,SAAS,MAAM,SAAS,KAAK,IAAI,CAAC;AAC/D,QAAM,UAAU,WAAW,KAAK,KAAK,CAAC;AACtC,MAAI,CAAC,QAAQ,OAAQ,QAAO;AAC5B,QAAM,WAAW,MAAM,KAAK,CAAC,SAAS,KAAK,SAAS,QAAQ;AAC5D,MAAI,YAAY,CAAC,OAAO,SAAS,QAAQ,EAAG,QAAO,KAAK,QAAQ;AAChE,SAAO,CAAC,GAAG,QAAQ,GAAI,MAAM,OAAO,KAAK,CAAC,CAAE;AAC9C;AAEA,SAAS,UAAU,OAA8B,MAAsB;AACrE,SAAO,OAAO,OAAO,MAAM,MAAM,EAAE,OAAO,CAAC,UAAU,MAAM,SAAS,QAAQ,KAAK,KAAK,CAAC,EAAE;AAC3F;AAEA,SAAS,UACP,MACA,SACA,MACoB;AACpB,MAAI,SAAS,KAAM,QAAO;AAC1B,QAAM,UAAU,KAAK,MAAM,QAAQ,IAAI;AACvC,QAAM,QAAQ,WAAW,QAAQ,OAAO,OAAO,QAAQ,QAAQ;AAC/D,MAAI,SAAS,QAAQ,OAAO;AAC1B,WAAO;AAAA,MACL,MAAM;AAAA,MACN,KAAK,uCAAuC,KAAK,yBAAyB,QAAQ,OAAO,UAAU;AAAA;AAAA,IACrG;AACF,OAAK,MAAM,QAAQ,IAAI,IAAI,EAAE,IAAI,MAAM,OAAO,QAAQ,EAAE;AACxD,SAAO;AACT;AAEO,SAAS,YACd,SACA,QACA,MACa;AACb,QAAM,EAAE,OAAO,IAAI,IAAI;AACvB,QAAM,QAAQ,QAAQ,SAAS,QAAQ,QAAQ,MAAM,KAAK;AAC1D,QAAM,WAAW,QAAQ,YAAY,QAAQ,MAAM;AACnD,QAAM,SAAS,UAAU,OAAO,QAAQ,SAAS,QAAQ,MAAM,OAAO,GAAG;AACzE,QAAM,eAAe,CAAC,QAAQ,MAAM,QAAQ,QAAQ,YAAY,EAAE,OAAO,OAAO,EAAE,KAAK,MAAM;AAC7F,SAAO;AAAA,IACL,KAAK,QAAQ,OAAO,UAAU,QAAQ,KAAK,MAAM;AAAA,IACjD,GAAI,eAAe,EAAE,aAAa,IAAI,CAAC;AAAA,IACvC,GAAI,QAAQ,EAAE,MAAM,IAAI,CAAC;AAAA,IACzB,GAAI,WAAW,EAAE,eAAe,SAAyC,IAAI,CAAC;AAAA,IAC9E,GAAI,SAAS,EAAE,OAAO,OAAO,IAAI,CAAC;AAAA,IAClC,GAAI,KAAK,SAAS,SAAS,EAAE,YAAY,EAAE,QAAQ,KAAK,QAAQ,EAAE,IAAI,CAAC;AAAA,EACzE;AACF;AAEA,eAAe,UACb,IACA,OACA,MACA,OACA,SACe;AACf,QAAM,SAAS,WAAW,QAAQ,SAAS,QAAQ,MAAM,KAAK;AAC9D,QAAM,SAAS,MAAM,OAAO,QAAQ,UAAU,EAAE,GAAG;AACnD,QAAM,aAAa,MAAM,GAAG,IAAI,aAAa,UAAU,IAAI,GAAG;AAC9D,MAAI,WAAW,QAAQ,cAAc;AACnC,KAAC,MAAM,GAAG,IAAI,aAAa,KAAK,GAAG,QAAQ,UAAU;AACzD;AAEA,SAAS,YACP,SACA,QACA,cACA,QACA,SACa;AACb,SAAO;AAAA,IACL,MAAM,QAAQ,KAAK,KAAK,KAAK;AAAA,IAC7B;AAAA,IACA,MAAM,QAAQ;AAAA,IACd;AAAA,IACA;AAAA,IACA,MAAM,QAAQ,MAAM,QAAQ;AAAA,IAC5B,GAAI,QAAQ,MAAM,SAAS,EAAE,QAAQ,QAAQ,KAAK,OAAO,IAAI,CAAC;AAAA,IAC9D,GAAI,QAAQ,MAAM,UAAU,QAAQ,SAAS,EAAE,QAAQ,QAAQ,OAAO,IAAI,CAAC;AAAA,IAC3E,GAAI,QAAQ,MAAM,UAAU,EAAE,SAAS,QAAQ,KAAK,QAAQ,IAAI,CAAC;AAAA,IACjE,MAAM,QAAQ,QAAQ;AAAA,IACtB,QAAQ,QAAQ,UAAU,QAAQ;AAAA,IAClC,OAAO,QAAQ,SAAS;AAAA,IACxB,OAAO,QAAQ,SAAS;AAAA,IACxB;AAAA,IACA,SAAS;AAAA,IACT,MAAM;AAAA,EACR;AACF;AAEA,eAAe,MAAM,MAAY,SAAuB,SAAmC;AACzF,QAAM,OAAO,MAAM,SAAS,MAAM,QAAQ,SAAS,OAAO;AAC1D,MAAI,KAAM,QAAO;AACjB,QAAM,OAAO,MAAM,KAAK;AACxB,QAAM,EAAE,OAAO,IAAI;AACnB,QAAM,SAAS,MAAM,SAAS,MAAM,QAAQ,MAAM,OAAO;AACzD,QAAM,QAAQ,UAAU,OAAO,MAAM,GAAG,QAAQ,IAAI;AACpD,MAAI,SAAS,QAAQ,OAAO;AAC1B,WAAO;AAAA,MACL,MAAM;AAAA,MACN,KAAK,mCAAmC,KAAK,8BAA8B,QAAQ,OAAO,aAAa;AAAA;AAAA,IACzG;AACF,QAAM,UAAU,QAAQ,YAAY,MAAM,KAAK,QAAQ,OAAO,IAAI;AAClE,QAAM,OAAO,QAAQ,YAAY,MAAM,UAAU,QAAQ,OAAO,IAAI;AACpE,SAAO,OAAO,OAAO,OAAO,IAAI,QAAQ;AACtC,UAAM,OAAO,MAAM,GAAG,IAAI,YAAY;AACtC,UAAM,UAAU,UAAU,MAAmB,SAAS,IAAI;AAC1D,QAAI,QAAS,QAAO;AACpB,UAAM,SAAS,WAAW,KAAK,QAAQ,IAAI;AAC3C,UAAM,KAAK,QAAQ,MAAM;AACzB,UAAM,SAAS,MAAM,GAAG,WAAW,KAAK,MAAM,EAAE,QAAiB,MAAM;AAAA,MACrE,WAAW,EAAE,MAAM,eAAe;AAAA,MAClC,gBAAgB,OAAO;AAAA,MACvB,YAAY;AAAA,IACd,CAAC;AACD,UAAM,QAAQ,MAAM,GAAG,mBAAmB,EAAE,WAAW,EAAE,MAAM,QAAQ,QAAQ,OAAO,EAAE,CAAC;AACzF,UAAM,UAAU,IAAI,MAAM,IAAI,YAAY,SAAS,QAAQ,IAAI,CAAC;AAChE,UAAM,UAAU,IAAI,KAAK,OAAO,IAAI,MAAM,IAAI,OAAO;AACrD,QAAI,QAAQ,QAAQ,OAAQ,EAAC,MAAM,GAAG,IAAI,eAAe,MAAM,EAAE,GAAG,SAAS,QAAQ;AACrF,QAAI,OAAO,EAAE,IAAI,YAAY,SAAS,QAAQ,MAAM,IAAI,OAAO,MAAM,GAAG,OAAO;AAC/E,UAAM,SACJ,QAAQ,WAAW,SACf,QAAQ,YACN,QAAQ,QAAQ,IAAI,KACpB,OACF,QAAQ;AACd,UAAM,OAAiB,CAAC;AACxB,UAAM,QAAQ,QAAQ,UAAU,SAAY,SAAS,QAAQ;AAC7D,UAAM,OAAO,UAAU,KAAK,KAAK;AACjC,eAAW,UAAU,QAAQ;AAC3B,WAAK;AAAA,QACH,MAAM,QAAQ,MAAM,IAAI,OAAO,IAAI;AAAA,UACjC,OAAO;AAAA,UACP;AAAA,UACA,QAAQ,WAAW;AAAA,UACnB;AAAA,UACA;AAAA,UACA,OAAO,UAAU;AAAA,UACjB;AAAA,QACF,CAAC;AAAA,MACH;AACF,UAAM,SAAS,EAAE,MAAM,GAAG,KAAK,GAAG,MAAM;AAAA,GAAM,OAAO,KAAK;AAC1D,UAAM,QAAQ,UAAU,IAAI,EAAE,QAAQ,cAAc,OAAO,MAAM,EAAE,GAAG,OAAO,KAAK,CAAC;AACnF,aAAS,MAAmB,QAAQ,SAAS,MAAM;AACnD,WAAO;AAAA,EACT,GAAG,OAAO;AACZ;AAEO,SAAS,UAAU,OAA8B,OAA8B;AACpF,MAAI,UAAU,KAAM,QAAO;AAC3B,MAAI,MAAM,WAAW,OAAO,EAAG,QAAO,MAAM,MAAM,MAAM,MAAM,QAAQ,MAAM,CAAC,GAAG,QAAQ;AACxF,SAAO,MAAM,OAAO,KAAK,GAAG,QAAQ;AACtC;AAEA,MAAM,UAAU,CAAC,QAAwB;AAAA,EACvC,MAAM;AAAA,EACN,KAAK,+BAA+B,GAAG,QAAQ,UAAU,EAAE,CAAC;AAAA;AAC9D;AAEA,eAAe,KACb,MACA,IACA,QACA,SACA,SACiB;AACjB,QAAM,OAAO,MAAM,SAAS,MAAM,QAAQ,SAAS,OAAO;AAC1D,MAAI,KAAM,QAAO;AACjB,QAAM,EAAE,SAAS,OAAO,IAAI,MAAM,KAAK;AACvC,QAAM,SAAS,OAAO,MAAM,EAAE,OAAO,EAAE;AACvC,MAAI,CAAC,UAAU,CAAC,KAAK,MAAM,EAAG,QAAO,QAAQ,EAAE;AAC/C,QAAM,SAAS,MAAM,SAAS,MAAM,OAAO,MAAM,OAAO;AACxD,QAAM,UAAU,QAAQ,YAAY,MAAM,KAAK,QAAQ,OAAO,IAAI;AAClE,QAAM,EAAE,OAAO,IAAI;AACnB,SAAO,QAAQ,OAAO,OAAO,OAAO;AAClC,QAAI,QAAQ,QAAQ,QAAQ;AAC1B,YAAM,MAAM,MAAM,GAAG,IAAI,eAAe,OAAO,YAA8B;AAC7E,UAAI,SAAS,eAAe,CAAC,GAAG,IAAI,QAAQ,GAAG,QAAQ,MAAM,CAAC;AAAA,IAChE;AACA,UAAM,QAAQ,MAAM,IAAI,OAAO,IAAI;AAAA,MACjC,OAAO;AAAA,MACP;AAAA,MACA,QAAQ,WAAW;AAAA,MACnB;AAAA,MACA,MAAM,UAAU,OAAO,MAAM,GAAG,MAAM;AAAA,MACtC,OAAO,WAAW;AAAA,MAClB;AAAA,MACA,UAAU,QAAQ;AAAA,MAClB,SAAS,QAAQ;AAAA,IACnB,CAAC;AACD,UAAM,SAAS,EAAE,MAAM,GAAG,KAAK,WAAW,OAAO,MAAM;AAAA,EAAK;AAC5D,aAAU,MAAM,GAAG,IAAI,YAAY,GAAiB,QAAQ,SAAS,MAAM;AAC3E,WAAO;AAAA,EACT,GAAG,OAAO;AACZ;AAEA,eAAe,OAAO,MAAY,QAAqB,SAAiC;AACtF,QAAM,EAAE,SAAS,OAAO,IAAI,MAAM,KAAK;AACvC,QAAM,eAAe,MAAM,QAAQ,aAAa,OAAO,cAAgC,OAAO;AAC9F,QAAM,cAAc,MAAM,SAAS,EAAE,YAAY,KAAK,CAAC;AACvD,QAAM,QAAQ,OAAO,OAAO,YAAY;AAC1C;AAEA,eAAe,UACb,MACA,OACA,MACA,SACA;AACA,QAAM,EAAE,QAAQ,IAAI,MAAM,KAAK;AAC/B,QAAM,OAAQ,MAAM,QAAQ,SAAS,cAAc,OAAO,KAAM,EAAE,OAAO,CAAC,EAAE;AAC5E,QAAM,UAAoB,CAAC;AAC3B,aAAW,CAAC,MAAM,KAAK,KAAK,OAAO,QAAQ,KAAK,KAAK,GAAG;AACtD,QAAI,MAAM,UAAU,SAAU,MAAM,KAAK,KAAK,EAAI;AAClD,UAAM,SAAS,MAAM,QAAQ,QAAQ,OAAO,IAAI,GAAa,OAAO;AACpE,QAAI,UAAU,OAAO,MAAM,WAAW;AACpC,YAAM,QAAQ,UAAU,OAAO,IAAI,GAAa,OAAO;AACzD,YAAQ,KAAK,IAAI;AAAA,EACnB;AACA,MAAI,QAAQ;AACV,UAAM,QAAQ,OAAO,OAAO,OAAO;AACjC,YAAM,MAAM,MAAM,GAAG,IAAI,YAAY;AACrC,iBAAW,QAAQ,QAAS,QAAO,IAAI,MAAM,IAAI;AAAA,IACnD,GAAG,OAAO;AACZ,SAAO,QAAQ;AACjB;AAEA,eAAe,KAAK,MAAY,IAAY,WAAoB,SAAmC;AACjG,QAAM,EAAE,QAAQ,OAAO,SAAS,OAAO,IAAI,MAAM,KAAK;AACtD,QAAM,SAAS,OAAO,MAAM,EAAE,OAAO,EAAE;AACvC,MAAI,CAAC,UAAU,CAAC,KAAK,MAAM,EAAG,QAAO,QAAQ,EAAE;AAC/C,QAAM,UAAU,MAAM,IAAI,YAAY,OAAO,OAAO;AACpD,QAAM,OAAO,MAAM,QAAQ,OAAO;AAClC,QAAM,OAAO,YACT,MAAM,KAAK,MAAM,SAAS,MAAM,OAAO,MAAM,OAAO,GAAG,OAAO,IAC9D,EAAE,IAAI,GAAG,IAAI,EAAE;AACnB,QAAM,OAAO,OAAO,CAAC,KAAK,UAAU;AAClC,IAAC,MAAM,OAAO,EAAE,EAAkB,UAAU;AAAA,EAC9C,GAAG,OAAO;AACV,QAAM,QAAQ,OAAO,UAAU,OAAO,MAAM;AAC5C,QAAM,UAAU,MAAM,OAAO,OAAO,OAAO,EAAE,WAAW,MAAM,OAAO,KAAK,GAAG,OAAO;AACpF,QAAM,SAAS,SAAS,KAAK,WAAW,KAAK,KAAK,QAAQ,KAAK;AAC/D,SAAO;AAAA,IACL,MAAM;AAAA,IACN,KAAK,WAAW,OAAO,MAAM,6BAA6B,MAAM,6BAA6B,OAAO,QAAQ,OAAO,QAAQ,OAAO,IAAI,CAAC;AAAA;AAAA,EACzI;AACF;AAEA,eAAe,OAAO,MAAY,IAAY,MAAc,SAAmC;AAC7F,QAAM,EAAE,OAAO,IAAI,MAAM,KAAK;AAC9B,QAAM,SAAS,OAAO,MAAM,EAAE,OAAO,EAAE;AACvC,MAAI,CAAC,UAAU,CAAC,KAAK,MAAM,EAAG,QAAO,QAAQ,EAAE;AAC/C,QAAM,SAAS,KAAK,KAAK;AACzB,MAAI,CAAC,OAAQ,QAAO,EAAE,MAAM,GAAG,KAAK,4CAA4C;AAChF,QAAM,OAAO,OAAO,CAAC,KAAK,UAAU;AAClC,IAAC,MAAM,OAAO,EAAE,EAAkB,OAAO;AAAA,EAC3C,GAAG,OAAO;AACV,SAAO,EAAE,MAAM,GAAG,KAAK,GAAG,OAAO,MAAM,kBAAkB,MAAM;AAAA,EAAK;AACtE;AAEA,eAAe,eACb,MACA,QACA,SACkB;AAClB,QAAM,EAAE,MAAM,IAAI;AAClB,MAAI,CAAC,MAAO,QAAO;AACnB,QAAM,QAAQ,UAAU,QAAQ,KAAK,MAAM;AAC3C,QAAM,UAAU,MAAM,MAAM,OAAO,OAAO,EAAE,WAAW,MAAM,OAAO,KAAK,GAAG,OAAO;AACnF,MAAI,CAAC,QAAQ,GAAI,QAAO;AACxB,MAAI,KAAK,QAAQ,MAAO,QAAO;AAC/B,UAAQ,MAAM,MAAM,UAAU,OAAO,EAAE,WAAW,KAAK,GAAG,OAAO,GAAG;AACtE;AAIA,eAAe,UACb,MACA,QACA,IACA,QACA,MACA,QACA,SAC2C;AAC3C,QAAM,OAAO,MAAM,KAAK;AACxB,QAAM,EAAE,SAAS,MAAM,IAAI;AAC3B,MAAI,CAAE,MAAM,KAAK,OAAO,OAAO,GAAI;AACjC,QAAI,KAAK,MAAM,GAAG;AAChB,YAAM,UAAU,MAAM,IAAI,YAAY,OAAO,OAAO;AACpD,YAAM,OAAO,MAAM,QAAQ,OAAO;AAClC,aAAO,QAAQ,KAAK,OAAO,IAAI;AAAA,IACjC;AACA,WAAO,EAAE,MAAM,KAAK;AAAA,EACtB;AACA,MAAI,OAAO,YAAY,MAAM;AAC3B,QAAI,MAAM,KAAK,OAAO,OAAO,EAAG,QAAO;AACvC,UAAM,QAAQ,MAAM,eAAe,MAAM,OAAO,QAAQ,OAAO;AAC/D,WAAO,SAAS;AAAA,MACd,QAAQ,OAAO,OAAO,GAAG,OAAO,IAAI;AAAA,IACtC;AACA,WAAO,EAAE,SAAS,KAAK;AAAA,EACzB;AACA,QAAM,YAAY,MAAM,UAAU,MAAM,IAAI,CAAC,UAAU,KAAK,MAAM,OAAO,GAAG,OAAO;AACnF,MAAI,CAAC,UAAW,QAAO;AACvB,QAAM,eAAe,MAAM,QAAQ,aAAa,OAAO,cAAgC,OAAO;AAC9F,QAAM,cAAc,MAAM,OAAO;AACjC,QAAM,MAAM,OAAO,QAAQ,MAAM,IAAI,gBAAgB,IAAI,OAAO;AAChE,SAAO;AACT;AAEA,eAAe,QACb,MACA,QACA,MACA,SACkB;AAClB,QAAM,EAAE,SAAS,OAAO,IAAI,MAAM,KAAK;AACvC,QAAM,OAAO,CAAC,OACZ,QAAQ,OAAO,CAAC,OAAO,GAAG,aAAa,EAAoB,GAAG,OAAO;AACvE,QAAM,OAAa,OAAO,SACxB,SAAS,QAAQ,KAAK,OAAO,KAAM,MAAM,QAAQ,MAAM,KAAK,IAAI,IAAI;AACtE,QAAM,SAAkB,EAAE,SAAS,CAAC,GAAG,UAAU,CAAC,EAAE;AACpD,QAAM,UAA4C,CAAC;AACnD,aAAW,CAAC,IAAI,MAAM,KAAK,OAAO,QAAQ,OAAO,MAAM,EAAE,MAAM,GAAG;AAChE,QAAI,OAAO,SAAS,UAAU,OAAO,KAAM;AAC3C,UAAM,SAAS,MAAM,UAAU,MAAM,QAAQ,IAAI,QAAQ,MAAM,QAAQ,OAAO;AAC9E,QAAI,OAAQ,SAAQ,KAAK,CAAC,IAAI,MAAM,CAAC;AAAA,EACvC;AACA,MAAI,QAAQ;AACV,UAAM,OAAO,OAAO,CAAC,KAAK,UAAU;AAClC,iBAAW,CAAC,IAAI,MAAM,KAAK,QAAS,QAAO,OAAO,MAAM,OAAO,EAAE,GAAkB,MAAM;AAAA,IAC3F,GAAG,OAAO;AACZ,SAAO;AACT;AAEA,eAAe,KAAK,MAAY,QAAuB,SAA2C;AAChG,QAAM,EAAE,OAAO,IAAI,MAAM,KAAK;AAC9B,QAAM,MAAsB,CAAC;AAC7B,aAAW,CAAC,IAAI,MAAM,KAAK,OAAO,QAAQ,OAAO,MAAM,EAAE,MAAM,GAAG;AAChE,QAAK,WAAW,QAAQ,OAAO,SAAS,UAAW,CAAC,KAAK,MAAM,EAAG;AAClE,QAAI,KAAK;AAAA,MACP;AAAA,MACA,QAAQ,OAAO;AAAA,MACf,MAAM,OAAO;AAAA,MACb,MAAM,OAAO;AAAA,MACb,MAAM,MAAM,OAAO,MAAM,OAAO,cAAc,OAAO;AAAA,IACvD,CAAC;AAAA,EACH;AACA,SAAO;AACT;AAEA,eAAe,QAAQ,MAAY,KAAwB,SAAqC;AAC9F,QAAM,EAAE,SAAS,OAAO,IAAI,MAAM,KAAK;AACvC,QAAM,QAAQ,OAAO,QAAQ,MAAM,QAAQ,SAAS,cAAc,OAAO,IAAI,SAAS,CAAC,CAAC;AACxF,QAAM,MAAgB,CAAC;AACvB,aAAW,MAAM,KAAK;AACpB,UAAM,SAAS,OAAO,MAAM,EAAE,OAAO,EAAE;AACvC,QAAI,CAAC,OAAQ;AACb,QACE,MAAM,KAAK,CAAC,UAAU,MAAM,UAAU,EAAE,KACvC,MAAM,OAAO,MAAM,OAAO,cAAc,OAAO;AAEhD,UAAI,KAAK,EAAE;AAAA,EACf;AACA,SAAO;AACT;AAEA,eAAe,eACb,MACA,QACA,KACA,UACA,QACA,SACA;AACA,QAAM,EAAE,QAAQ,IAAI,MAAM,KAAK;AAC/B,QAAM,SAAS,MAAM,SAAS,MAAM,QAAQ,OAAO;AACnD,QAAM,QAAQ;AAAA,IACZ,CAAC,OACC,GAAG;AAAA,MACD,KAAK,MAAM,EAAE;AAAA,MACb,EAAE,QAAQ,KAAK,MAAM,QAAQ,UAAU,GAAI,OAAO,SAAS,EAAE,OAAO,IAAI,CAAC,EAAG;AAAA,MAC5E,EAAE,WAAW,EAAE,MAAM,eAAe,GAAG,gBAAgB,OAAO,IAAI,YAAY,KAAK;AAAA,IACrF;AAAA,IACF;AAAA,EACF;AACF;AAEA,eAAe,OAAO,MAAY,OAA0B,QAAgB,SAAkB;AAC5F,QAAM,EAAE,QAAQ,IAAI,MAAM,KAAK;AAC/B,QAAM,QAAQ,OAAO,OAAO,OAAO;AACjC,UAAM,OAAO,MAAM,GAAG,IAAI,YAAY;AACtC,eAAW,QAAQ,OAAO;AACxB,YAAM,QAAQ,KAAK,MAAM,OAAO,IAAI,CAAC;AACrC,UAAI,CAAC,MAAO;AACZ,YAAM,SAAS;AACf,YAAM,SAAS;AACf,YAAM,UAAU;AAAA,IAClB;AAAA,EACF,GAAG,OAAO;AACZ;AAEA,eAAe,KACb,MACA,IACA,MACA,QACA,SACiB;AACjB,QAAM,EAAE,QAAQ,MAAM,IAAI,MAAM,KAAK;AACrC,QAAM,SAAS,OAAO,MAAM,EAAE,OAAO,EAAE;AACvC,MAAI,CAAC,UAAU,CAAC,KAAK,MAAM,EAAG,QAAO,QAAQ,EAAE;AAC/C,QAAM,QAAQ,GAAG,OAAO,IAAI,KAAK,OAAO,QAAQ,OAAO;AACvD,QAAM,MAAM;AAAA,IACV;AAAA,MACE,SAAS;AAAA,MACT,QAAQ,GAAG,EAAE;AAAA,MACb,OAAO;AAAA,MACP,MAAM,UAAU,KAAK;AAAA,MACrB,MAAM;AAAA,MACN,QAAQ,QAAQ,OAAO,IAAI;AAAA,MAC3B,GAAI,OAAO,SAAS,EAAE,OAAO,IAAI,CAAC;AAAA,IACpC;AAAA,IACA;AAAA,EACF;AACA,SAAO,EAAE,MAAM,GAAG,KAAK,0BAA0B;AACnD;AAEO,SAAS,aAAa,MAA2B,OAAyB;AAC/E,QAAM,OAAa,EAAE,MAAM,MAAM;AACjC,SAAO;AAAA,IACL,QAAQ,CAAC,MAAyB,QAAgB,YAChD,OAAO,MAAM,MAAM,QAAQ,OAAO;AAAA,IACpC,MAAM,CAAC,IAAY,MAAc,QAAmC,YAClE,KAAK,MAAM,IAAI,MAAM,QAAQ,OAAO;AAAA,IACtC,SAAS,OAAO,SAAwB,MAAM,KAAK,MAAM,QAAQ,QAAQ,GAAG;AAAA,IAC5E,OAAO,CAAC,SAAuB,YAAqB,MAAM,MAAM,SAAS,OAAO;AAAA,IAChF,MAAM,CAAC,IAAY,QAAgB,SAAsB,YACvD,KAAK,MAAM,IAAI,QAAQ,SAAS,OAAO;AAAA,IACzC,MAAM,CAAC,IAAY,WAAoB,YAAqB,KAAK,MAAM,IAAI,WAAW,OAAO;AAAA,IAC7F,QAAQ,CAAC,IAAY,MAAc,YAAqB,OAAO,MAAM,IAAI,MAAM,OAAO;AAAA,IACtF,SAAS,CAAC,QAAgB,MAAoB,YAC5C,QAAQ,MAAM,QAAQ,MAAM,OAAO;AAAA,IACrC,MAAM,CAAC,QAAuB,YAAqB,KAAK,MAAM,QAAQ,OAAO;AAAA,IAC7E,MAAM,CAAC,cAAsB,YAAqB,OAAO,MAAM,cAAc,OAAO;AAAA,IACpF,SAAS,CAAC,KAAwB,YAAqB,QAAQ,MAAM,KAAK,OAAO;AAAA,IACjF,gBAAgB,CACd,QACA,KACA,UACA,QACA,YACG,eAAe,MAAM,QAAQ,KAAK,UAAU,QAAQ,OAAO;AAAA,EAClE;AACF;AAEO,SAAS,QACd,OACmD;AACnD,MAAI,CAAC,MAAO,QAAO;AACnB,QAAM,KAAK,MAAM,QAAQ,GAAG;AAC5B,MAAI,MAAM,EAAG,QAAO;AACpB,SAAO,EAAE,UAAU,MAAM,MAAM,GAAG,EAAE,GAAG,SAAS,MAAM,MAAM,KAAK,CAAC,EAAE;AACtE;",
4
+ "sourcesContent": ["import type { Context } from '@earendil-works/chord';\nimport {\n type AgentChange,\n type AnyTask,\n type Conversation,\n type ConversationId,\n configure,\n defineDoc,\n type Extension,\n type Harness,\n type TaskId,\n type ToolRegistration,\n type Tx,\n} from '@earendil-works/pi-durable';\nimport type { ExecutionEnv } from '@earendil-works/pi-durable/env';\nimport {\n type Agents,\n type AgentsState,\n freeFolder,\n live,\n type Mark,\n type ScoopRecord,\n scoopId,\n} from '../agents.ts';\nimport { deltasOnly } from '../checkpoints.ts';\nimport { CODEMODE } from '../codemode/index.ts';\nimport { distinctTaints, GuestTaintDoc, type InheritedTaint } from '../guests/guard.ts';\nimport type { ProcessGroups } from '../kernel/groups.ts';\nimport { type Layout, LEGACY } from '../layout.ts';\nimport type { Licks } from '../licks/licks.ts';\nimport { McpAllowDoc, mcpEntries } from '../mcp/index.ts';\nimport type { Role } from '../roles/roles.ts';\nimport type { Choosable } from '../selection.ts';\nimport { visible } from './visible.ts';\n\nexport { SCOOPS_ROOT } from '../layout.ts';\nexport const LEDGER_SIZE = 512;\n\nexport type Feed = {\n scoop: string;\n created: Mark | null;\n report: boolean;\n target: string | null;\n channel: 'scoop-notify' | 'bash';\n from?: string;\n agent?: boolean;\n};\ntype Wait = { scoops: string[]; done: Record<string, string>; cone: string };\nexport type Answer = { code: number; out: string; err?: string; tasks?: number[] };\ntype WorkState = {\n feeds: Record<string, Feed>;\n waits: Record<string, Wait>;\n ledger: Record<string, Answer>;\n turns: Record<string, { at: number; count: number }>;\n};\n\nexport const ScoopWorkDoc = defineDoc<WorkState>({\n kind: 'slicc.scoops.work',\n checkpointWhen: deltasOnly,\n version: 1,\n scope: 'session',\n initial: () => ({ feeds: {}, waits: {}, ledger: {}, turns: {} }),\n});\n\nexport interface ScoopTasks {\n anchor: AnyTask;\n reporter: AnyTask;\n wait: AnyTask;\n}\n\nexport type EnvOf = (\n conversationId: ConversationId,\n context: Context\n) => Promise<Pick<ExecutionEnv, 'canonicalPath'> | undefined>;\n\nexport interface ScoopsHost {\n harness: Harness;\n agents: Agents;\n licks: Licks;\n groups?: ProcessGroups;\n tools?: readonly ToolRegistration[];\n reads?: () => readonly string[];\n files?: Pick<ExecutionEnv, 'remove' | 'createDir'>;\n envOf?: EnvOf;\n mcp?: (names: readonly string[]) => ToolRegistration[];\n layout?: Layout;\n enforced?: boolean;\n exclude?: readonly Extension[];\n}\n\nexport interface Rewound {\n stopped: string[];\n restored: string[];\n}\n\nexport interface ScoopSummary {\n id: string;\n folder: string;\n name: string;\n role: string | null;\n busy: boolean;\n}\n\nexport interface Limits {\n maxLiveScoops: number;\n maxPerTurn: number;\n}\n\nexport interface SpawnRequest {\n cone: string;\n kind?: 'async' | 'sync';\n parent?: string;\n depth?: number;\n roots?: { write: string[]; read: string[] };\n cwd?: string;\n origin?: string;\n instructions?: string;\n target?: string | null;\n asker?: string | null;\n name: string;\n role?: Role;\n model?: { provider: string; modelId: string };\n thinking?: AgentChange['thinkingLevel'];\n tools?: string[];\n prompts: string[];\n fromAgent: boolean;\n request?: string;\n limits: Limits;\n taints?: InheritedTaint[];\n created?: (tx: Tx, made: Spawned) => Promise<void>;\n}\n\nexport interface FeedOptions {\n fromAgent: boolean;\n request: string;\n followUp: boolean;\n target: string | null;\n taints?: InheritedTaint[];\n}\n\nexport interface Spawned {\n folder: string;\n conversation: number;\n tasks: number[];\n}\n\nexport function workspace(folder: string, layout: Layout = LEGACY): string {\n return layout.workspace(folder);\n}\n\nexport async function tail(conversation: Conversation, context: Context): Promise<Mark> {\n const { entries } = await conversation.context(context);\n return { in: conversation.id, at: Number(entries.at(-1)?.id ?? 0) };\n}\n\nexport async function turnStart(conversation: Conversation, context: Context): Promise<number> {\n const { entries } = await conversation.context(context);\n return Number(entries.findLast((entry) => entry.kind === 'pi.user')?.id ?? 0);\n}\n\nexport function coneOf(state: Readonly<AgentsState>, conversation: number): string | undefined {\n return Object.entries(state.cones).find(([, cone]) => cone.conversation === conversation)?.[0];\n}\n\nexport function findScoop(\n state: Readonly<AgentsState>,\n handle: string,\n cone: string | null\n): [string, ScoopRecord] | undefined {\n const id = handle.startsWith('scoop:') ? handle : scoopId(handle);\n const reachable = (record: ScoopRecord | undefined): record is ScoopRecord =>\n !!record && live(record) && (cone === null || record.cone === cone);\n const record = state.scoops[id];\n if (reachable(record)) return [id, record];\n return Object.entries(state.scoops).find(\n ([, candidate]) => reachable(candidate) && candidate.name === handle\n );\n}\n\nfunction remember(work: WorkState, request: string | undefined, answer: Answer): void {\n if (!request) return;\n work.ledger[request] = answer;\n const keys = Object.keys(work.ledger);\n for (const key of keys.slice(0, Math.max(0, keys.length - LEDGER_SIZE))) delete work.ledger[key];\n}\n\ntype Core = { host: Promise<ScoopsHost>; tasks: () => ScoopTasks };\n\nasync function coneOfId(core: Core, coneId: string, context: Context): Promise<Conversation> {\n const { agents } = await core.host;\n const found = await agents.conversation(coneId, context);\n if (!found) throw new Error(`There is no cone ${coneId}.`);\n return found;\n}\n\nasync function isBusy(core: Core, conversation: number, context: Context): Promise<boolean> {\n const { harness } = await core.host;\n const handle = await harness.conversation(conversation as ConversationId, context);\n const view = await handle?.viewState(context);\n const run = (view?.value.docs['pi.live'] as { run?: unknown } | undefined)?.run;\n view?.dispose();\n return Boolean(run);\n}\n\nasync function answered(\n core: Core,\n request: string | undefined,\n context: Context\n): Promise<Answer | undefined> {\n if (!request) return undefined;\n const { harness } = await core.host;\n return (await harness.snapshot(ScoopWorkDoc, context))?.ledger[request];\n}\n\ntype NewFeed = Omit<Feed, 'channel' | 'from'> & {\n from: string;\n agent: boolean;\n prompt: string;\n request?: string;\n followUp?: boolean;\n};\n\nasync function addFeed(core: Core, tx: Tx, parent: number, feed: NewFeed): Promise<number> {\n const task = await tx.createTask(\n core.tasks().reporter as never,\n {\n scoop: feed.scoop,\n prompt: feed.prompt,\n ...(feed.followUp ? { followUp: true } : {}),\n ...(feed.request ? { request: feed.request } : {}),\n },\n {\n ownership: { kind: 'conversation' },\n conversationId: parent as ConversationId,\n background: true,\n }\n );\n (await tx.doc(ScoopWorkDoc)).feeds[String(task)] = {\n scoop: feed.scoop,\n created: feed.created,\n report: feed.report,\n target: feed.target,\n channel: 'scoop-notify',\n from: feed.from,\n agent: feed.agent,\n };\n return Number(task);\n}\n\nexport function choosable(tools: readonly ToolRegistration[]): Choosable {\n const names = new Set(tools.map((tool) => tool.name));\n return (name) => names.has(name) || (mcpEntries([name]) ?? []).length > 0;\n}\n\nfunction selection(\n tools: readonly ToolRegistration[] | undefined,\n names: string[] | undefined,\n mcp?: (names: readonly string[]) => ToolRegistration[]\n) {\n if (!names || !tools) return undefined;\n const picked = tools.filter((tool) => names.includes(tool.name));\n const entries = mcpEntries(names) ?? [];\n if (!entries.length) return picked;\n const codemode = tools.find((tool) => tool.name === CODEMODE);\n if (codemode && !picked.includes(codemode)) picked.push(codemode);\n return [...picked, ...(mcp?.(entries) ?? [])];\n}\n\nfunction liveCount(state: Readonly<AgentsState>, cone: string): number {\n return Object.values(state.scoops).filter((scoop) => scoop.cone === cone && live(scoop)).length;\n}\n\nfunction claimTurn(\n work: WorkState,\n request: SpawnRequest,\n turn: number | null\n): Answer | undefined {\n if (turn === null) return undefined;\n const counted = work.turns[request.cone];\n const count = counted && counted.at === turn ? counted.count : 0;\n if (count >= request.limits.maxPerTurn)\n return {\n code: 1,\n out: `subagent: this turn already started ${count} scoops (the limit is ${request.limits.maxPerTurn})\\n`,\n };\n work.turns[request.cone] = { at: turn, count: count + 1 };\n return undefined;\n}\n\nexport function agentChange(\n request: SpawnRequest,\n folder: string,\n host: Pick<ScoopsHost, 'tools' | 'mcp' | 'layout' | 'exclude'>\n): AgentChange {\n const { tools, mcp } = host;\n const model = request.model ?? modelOf(request.role?.model);\n const thinking = request.thinking ?? request.role?.thinking;\n const chosen = selection(tools, request.tools ?? request.role?.tools, mcp);\n const instructions = [request.role?.prompt, request.instructions].filter(Boolean).join('\\n\\n');\n return {\n cwd: request.cwd ?? workspace(folder, host.layout),\n ...(instructions ? { instructions } : {}),\n ...(model ? { model } : {}),\n ...(thinking ? { thinkingLevel: thinking as AgentChange['thinkingLevel'] } : {}),\n ...(chosen ? { tools: chosen } : {}),\n ...(host.exclude?.length ? { extensions: { remove: host.exclude } } : {}),\n };\n}\n\nasync function narrowMcp(\n tx: Tx,\n state: Readonly<AgentsState>,\n cone: ConversationId,\n child: ConversationId,\n request: SpawnRequest\n): Promise<void> {\n const listed = mcpEntries(request.tools ?? request.role?.tools);\n const caller = state.scoops[request.parent ?? '']?.conversation as ConversationId | undefined;\n const inherited = (await tx.doc(McpAllowDoc, caller ?? cone)).allow;\n if (listed !== null || inherited !== null)\n (await tx.doc(McpAllowDoc, child)).allow = listed ?? inherited;\n}\n\nfunction scoopRecord(\n request: SpawnRequest,\n folder: string,\n conversation: number,\n anchor: number,\n created: Mark | null\n): ScoopRecord {\n return {\n name: request.name.trim() || folder,\n folder,\n cone: request.cone,\n conversation,\n anchor,\n role: request.role?.name ?? null,\n ...(request.role?.memory ? { memory: request.role.memory } : {}),\n ...(request.role?.memory && request.origin ? { origin: request.origin } : {}),\n ...(request.role?.context ? { context: request.role.context } : {}),\n kind: request.kind ?? 'async',\n parent: request.parent ?? request.cone,\n depth: request.depth ?? 1,\n roots: request.roots ?? null,\n created,\n dropped: null,\n gone: false,\n };\n}\n\nasync function spawn(core: Core, request: SpawnRequest, context: Context): Promise<Answer> {\n const done = await answered(core, request.request, context);\n if (done) return done;\n const host = await core.host;\n const { agents } = host;\n const parent = await coneOfId(core, request.cone, context);\n const count = liveCount(agents.state(), request.cone);\n if (count >= request.limits.maxLiveScoops)\n return {\n code: 1,\n out: `subagent: this cone already has ${count} live scoops (the limit is ${request.limits.maxLiveScoops}); stop one first\\n`,\n };\n const created = request.fromAgent ? await tail(parent, context) : null;\n const turn = request.fromAgent ? await turnStart(parent, context) : null;\n return agents.update(async (tx, doc) => {\n const work = await tx.doc(ScoopWorkDoc);\n const refused = claimTurn(work as WorkState, request, turn);\n if (refused) return refused;\n const folder = freeFolder(doc, request.name);\n const id = scoopId(folder);\n const anchor = await tx.createTask(core.tasks().anchor as never, null, {\n ownership: { kind: 'conversation' },\n conversationId: parent.id,\n background: true,\n });\n const child = await tx.createConversation({ ownership: { kind: 'task', taskId: anchor } });\n await configure(tx, child.id, agentChange(request, folder, host));\n await narrowMcp(tx, doc, parent.id, child.id, request);\n if (request.taints?.length) (await tx.doc(GuestTaintDoc, child.id)).taints = request.taints;\n doc.scoops[id] = scoopRecord(request, folder, child.id, Number(anchor), created);\n const target =\n request.target === undefined\n ? request.fromAgent\n ? `cone:${request.cone}`\n : null\n : request.target;\n const made: number[] = [];\n const asker = request.asker === undefined ? target : request.asker;\n const from = askerName(doc, asker);\n for (const prompt of request.prompts)\n made.push(\n await addFeed(core, tx, parent.id, {\n scoop: id,\n created,\n report: target !== null,\n target,\n from,\n agent: asker !== null,\n prompt,\n })\n );\n const answer = { code: 0, out: `${folder}\\n`, tasks: made };\n await request.created?.(tx, { folder, conversation: Number(child.id), tasks: made });\n remember(work as WorkState, request.request, answer);\n return answer;\n }, context);\n}\n\nexport function askerName(state: Readonly<AgentsState>, asker: string | null): string {\n if (asker === null) return 'terminal';\n if (asker.startsWith('cone:')) return state.cones[asker.slice('cone:'.length)]?.name ?? asker;\n return state.scoops[asker]?.name ?? asker;\n}\n\nconst missing = (id: string): Answer => ({\n code: 1,\n out: `subagent: there is no scoop ${id.replace('scoop:', '')}\\n`,\n});\n\nasync function feed(\n core: Core,\n id: string,\n prompt: string,\n options: FeedOptions,\n context: Context\n): Promise<Answer> {\n const done = await answered(core, options.request, context);\n if (done) return done;\n const { harness, agents } = await core.host;\n const record = agents.state().scoops[id];\n if (!record || !live(record)) return missing(id);\n const parent = await coneOfId(core, record.cone, context);\n const created = options.fromAgent ? await tail(parent, context) : null;\n const { target } = options;\n return harness.commit(async (tx) => {\n if (options.taints?.length) {\n const doc = await tx.doc(GuestTaintDoc, record.conversation as ConversationId);\n doc.taints = distinctTaints([...doc.taints, ...options.taints]);\n }\n await addFeed(core, tx, parent.id, {\n scoop: id,\n created,\n report: target !== null,\n target,\n from: askerName(agents.state(), target),\n agent: target !== null,\n prompt,\n followUp: options.followUp,\n request: options.request,\n });\n const answer = { code: 0, out: `sent to ${record.folder}\\n` };\n remember((await tx.doc(ScoopWorkDoc)) as WorkState, options.request, answer);\n return answer;\n }, context);\n}\n\nasync function signal(core: Core, record: ScoopRecord, context: Context): Promise<void> {\n const { harness, groups } = await core.host;\n const conversation = await harness.conversation(record.conversation as ConversationId, context);\n await conversation?.abort(context, { background: true });\n await groups?.signal(record.conversation);\n}\n\nasync function stopFeeds(\n core: Core,\n scoop: string,\n keep: (feed: Feed) => Promise<boolean>,\n context: Context\n) {\n const { harness } = await core.host;\n const work = (await harness.snapshot(ScoopWorkDoc, context)) ?? { feeds: {} };\n const dropped: string[] = [];\n for (const [task, entry] of Object.entries(work.feeds)) {\n if (entry.scoop !== scoop || (await keep(entry))) continue;\n const record = await harness.getTask(Number(task) as TaskId, context);\n if (record && record.state.status !== 'terminal')\n await harness.abortTask(Number(task) as TaskId, context);\n dropped.push(task);\n }\n if (dropped.length)\n await harness.commit(async (tx) => {\n const doc = await tx.doc(ScoopWorkDoc);\n for (const task of dropped) delete doc.feeds[task];\n }, context);\n return dropped.length;\n}\n\nasync function stop(core: Core, id: string, fromAgent: boolean, context: Context): Promise<Answer> {\n const { agents, files, layout = LEGACY } = await core.host;\n const record = agents.state().scoops[id];\n if (!record || !live(record)) return missing(id);\n await stopFeeds(core, id, async () => false, context);\n await signal(core, record, context);\n const mark = fromAgent\n ? await tail(await coneOfId(core, record.cone, context), context)\n : { in: 0, at: 0 };\n await agents.update((_tx, state) => {\n (state.scoops[id] as ScoopRecord).dropped = mark;\n }, context);\n const place = layout.workspace(record.folder);\n const removed = await files?.remove(place, { recursive: true, force: true }, context);\n const folder = removed?.ok ? `removed ${place}` : `kept ${place}`;\n return {\n code: 0,\n out: `stopped ${record.folder}; its transcript is kept, ${folder}, and its reports stay in ${layout.reports(record.folder, record.cone)}\\n`,\n };\n}\n\nasync function rename(core: Core, id: string, name: string, context: Context): Promise<Answer> {\n const { agents } = await core.host;\n const record = agents.state().scoops[id];\n if (!record || !live(record)) return missing(id);\n const wanted = name.trim();\n if (!wanted) return { code: 2, out: 'subagent: rename needs a non-empty name\\n' };\n await agents.update((_tx, state) => {\n (state.scoops[id] as ScoopRecord).name = wanted;\n }, context);\n return { code: 0, out: `${record.folder} is now called ${wanted}\\n` };\n}\n\nasync function resetWorkspace(\n host: Pick<ScoopsHost, 'files' | 'layout'>,\n folder: string,\n context: Context\n): Promise<boolean> {\n const { files } = host;\n if (!files) return true;\n const place = workspace(folder, host.layout);\n const cleared = await files.remove(place, { recursive: true, force: true }, context);\n if (!cleared.ok) return false;\n if (host.layout?.users) return true;\n return (await files.createDir(place, { recursive: true }, context)).ok;\n}\n\ntype Seen = (mark: Mark | null) => Promise<boolean>;\n\nasync function rewindOne(\n core: Core,\n coneId: string,\n id: string,\n record: ScoopRecord,\n seen: Seen,\n result: Rewound,\n context: Context\n): Promise<Partial<ScoopRecord> | undefined> {\n const host = await core.host;\n const { harness, licks } = host;\n if (!(await seen(record.created))) {\n if (live(record)) {\n await stopFeeds(core, id, async () => false, context);\n await signal(core, record, context);\n result.stopped.push(record.name);\n }\n return { gone: true };\n }\n if (record.dropped !== null) {\n if (await seen(record.dropped)) return undefined;\n const reset = await resetWorkspace(host, record.folder, context);\n result.restored.push(\n reset ? record.name : `${record.name} (its working folder could not be reset)`\n );\n return { dropped: null };\n }\n const withdrawn = await stopFeeds(core, id, (entry) => seen(entry.created), context);\n if (!withdrawn) return undefined;\n const conversation = await harness.conversation(record.conversation as ConversationId, context);\n await conversation?.abort(context);\n await licks.forget(`cone:${coneId}`, 'scoop-notify', id, context);\n return undefined;\n}\n\nasync function rewound(\n core: Core,\n coneId: string,\n fork: Conversation,\n context: Context\n): Promise<Rewound> {\n const { harness, agents } = await core.host;\n const read = (id: number) =>\n harness.commit((tx) => tx.conversation(id as ConversationId), context);\n const seen: Seen = async (mark) =>\n mark === null || mark.in === 0 || (await visible(read, fork.id, mark));\n const result: Rewound = { stopped: [], restored: [] };\n const changes: [string, Partial<ScoopRecord>][] = [];\n for (const [id, record] of Object.entries(agents.state().scoops)) {\n if (record.cone !== coneId || record.gone) continue;\n const change = await rewindOne(core, coneId, id, record, seen, result, context);\n if (change) changes.push([id, change]);\n }\n if (changes.length)\n await agents.update((_tx, state) => {\n for (const [id, change] of changes) Object.assign(state.scoops[id] as ScoopRecord, change);\n }, context);\n return result;\n}\n\nasync function list(core: Core, coneId: string | null, context: Context): Promise<ScoopSummary[]> {\n const { agents } = await core.host;\n const out: ScoopSummary[] = [];\n for (const [id, record] of Object.entries(agents.state().scoops)) {\n if ((coneId !== null && record.cone !== coneId) || !live(record)) continue;\n out.push({\n id,\n folder: record.folder,\n name: record.name,\n role: record.role,\n busy: await isBusy(core, record.conversation, context),\n });\n }\n return out;\n}\n\nasync function working(core: Core, ids: readonly string[], context: Context): Promise<string[]> {\n const { harness, agents } = await core.host;\n const feeds = Object.values((await harness.snapshot(ScoopWorkDoc, context))?.feeds ?? {});\n const out: string[] = [];\n for (const id of ids) {\n const record = agents.state().scoops[id];\n if (!record) continue;\n if (\n feeds.some((entry) => entry.scoop === id) ||\n (await isBusy(core, record.conversation, context))\n )\n out.push(id);\n }\n return out;\n}\n\nasync function notifyWhenDone(\n core: Core,\n coneId: string,\n ids: string[],\n deadline: number,\n taints: readonly InheritedTaint[],\n context: Context\n) {\n const { harness } = await core.host;\n const parent = await coneOfId(core, coneId, context);\n await harness.commit(\n (tx) =>\n tx.createTask(\n core.tasks().wait as never,\n { scoops: ids, cone: coneId, deadline, ...(taints.length ? { taints } : {}) },\n { ownership: { kind: 'conversation' }, conversationId: parent.id, background: true }\n ),\n context\n );\n}\n\nasync function detach(core: Core, tasks: readonly number[], target: string, context: Context) {\n const { harness } = await core.host;\n await harness.commit(async (tx) => {\n const work = await tx.doc(ScoopWorkDoc);\n for (const task of tasks) {\n const entry = work.feeds[String(task)];\n if (!entry) continue;\n entry.report = true;\n entry.target = target;\n entry.channel = 'bash';\n }\n }, context);\n}\n\nasync function note(\n core: Core,\n id: string,\n text: string,\n taints: readonly InheritedTaint[],\n context: Context\n): Promise<Answer> {\n const { agents, licks } = await core.host;\n const record = agents.state().scoops[id];\n if (!record || !live(record)) return missing(id);\n const label = `${record.name} (${record.role ?? 'scoop'})`;\n await licks.deliver(\n {\n channel: 'scoop-notify',\n source: `${id}#note`,\n title: label,\n text: `[scoop ${label} progress]`,\n body: text,\n target: `cone:${record.cone}`,\n ...(taints.length ? { taints } : {}),\n },\n context\n );\n return { code: 0, out: 'note sent to the cone\\n' };\n}\n\nexport function createScoops(host: Promise<ScoopsHost>, tasks: () => ScoopTasks) {\n const core: Core = { host, tasks };\n return {\n detach: (made: readonly number[], target: string, context: Context) =>\n detach(core, made, target, context),\n note: (id: string, text: string, taints: readonly InheritedTaint[], context: Context) =>\n note(core, id, text, taints, context),\n lineage: async (pid: number | null) => (await core.host).groups?.lineage(pid),\n spawn: (request: SpawnRequest, context: Context) => spawn(core, request, context),\n feed: (id: string, prompt: string, options: FeedOptions, context: Context) =>\n feed(core, id, prompt, options, context),\n stop: (id: string, fromAgent: boolean, context: Context) => stop(core, id, fromAgent, context),\n rename: (id: string, name: string, context: Context) => rename(core, id, name, context),\n rewound: (coneId: string, fork: Conversation, context: Context) =>\n rewound(core, coneId, fork, context),\n list: (coneId: string | null, context: Context) => list(core, coneId, context),\n busy: (conversation: number, context: Context) => isBusy(core, conversation, context),\n working: (ids: readonly string[], context: Context) => working(core, ids, context),\n notifyWhenDone: (\n coneId: string,\n ids: string[],\n deadline: number,\n taints: readonly InheritedTaint[],\n context: Context\n ) => notifyWhenDone(core, coneId, ids, deadline, taints, context),\n };\n}\n\nexport function modelOf(\n value: string | undefined\n): { provider: string; modelId: string } | undefined {\n if (!value) return undefined;\n const at = value.indexOf('/');\n if (at <= 0) return undefined;\n return { provider: value.slice(0, at), modelId: value.slice(at + 1) };\n}\n\nexport type Scoops = ReturnType<typeof createScoops>;\n"],
5
+ "mappings": "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",
6
6
  "names": ["record", "feed"]
7
7
  }
@@ -1,9 +1,11 @@
1
1
  import { replicatedState } from "@earendil-works/chord";
2
2
  import { BACKGROUND_CONTEXT } from "@earendil-works/chord/context";
3
3
  import { defineDoc } from "@earendil-works/pi-durable";
4
+ import { deltasOnly } from "../checkpoints.js";
4
5
  const LEGACY_DATABASE = "slicc-agent-credentials";
5
6
  const MovedDoc = defineDoc({
6
7
  kind: "slicc.keys-moved",
8
+ checkpointWhen: deltasOnly,
7
9
  version: 1,
8
10
  scope: "session",
9
11
  initial: () => ({ accounts: [], dismissed: false })