shariq-pi-extensions 0.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 (123) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +94 -0
  3. package/THIRD_PARTY_NOTICES.md +11 -0
  4. package/docs/ARCHITECTURE.md +54 -0
  5. package/docs/DEVELOPMENT.md +88 -0
  6. package/docs/EXTENSIONS.md +89 -0
  7. package/extensions/antigravity-provider/LICENSE +21 -0
  8. package/extensions/antigravity-provider/README.md +23 -0
  9. package/extensions/antigravity-provider/antigravity/cloud-code-assist.ts +519 -0
  10. package/extensions/antigravity-provider/antigravity/index.ts +67 -0
  11. package/extensions/antigravity-provider/antigravity/models.ts +184 -0
  12. package/extensions/antigravity-provider/antigravity/oauth.ts +499 -0
  13. package/extensions/antigravity-provider/index.ts +3 -0
  14. package/extensions/ask-user/README.md +21 -0
  15. package/extensions/ask-user/index.ts +417 -0
  16. package/extensions/background-terminals/README.md +43 -0
  17. package/extensions/background-terminals/index.ts +400 -0
  18. package/extensions/background-terminals/src/manager.ts +480 -0
  19. package/extensions/background-terminals/src/output-buffer.ts +110 -0
  20. package/extensions/background-terminals/src/presentation.ts +74 -0
  21. package/extensions/background-terminals/src/types.ts +47 -0
  22. package/extensions/background-terminals/src/ui.ts +478 -0
  23. package/extensions/context-usage/LICENSE +21 -0
  24. package/extensions/context-usage/README.md +20 -0
  25. package/extensions/context-usage/index.ts +2006 -0
  26. package/extensions/context-usage/lib/ansi.ts +60 -0
  27. package/extensions/context-usage/lib/boundary.ts +27 -0
  28. package/extensions/context-usage/lib/chat.ts +190 -0
  29. package/extensions/context-usage/lib/config.ts +30 -0
  30. package/extensions/context-usage/lib/fmt.ts +59 -0
  31. package/extensions/context-usage/lib/style.ts +260 -0
  32. package/extensions/copy-all/README.md +15 -0
  33. package/extensions/copy-all/index.ts +72 -0
  34. package/extensions/factory-provider/API_KEYS.md +17 -0
  35. package/extensions/factory-provider/AUTH.md +15 -0
  36. package/extensions/factory-provider/README.md +90 -0
  37. package/extensions/factory-provider/REFRESH_MODELS.md +185 -0
  38. package/extensions/factory-provider/UPDATING.md +97 -0
  39. package/extensions/factory-provider/factory/api-keys.ts +407 -0
  40. package/extensions/factory-provider/factory/auth.ts +132 -0
  41. package/extensions/factory-provider/factory/constants.ts +15 -0
  42. package/extensions/factory-provider/factory/dashboard.ts +363 -0
  43. package/extensions/factory-provider/factory/droid.ts +84 -0
  44. package/extensions/factory-provider/factory/limits.ts +342 -0
  45. package/extensions/factory-provider/factory/models.ts +283 -0
  46. package/extensions/factory-provider/factory/responses.ts +331 -0
  47. package/extensions/factory-provider/factory/warm-theme.ts +53 -0
  48. package/extensions/factory-provider/factory/websocket.ts +130 -0
  49. package/extensions/factory-provider/index.ts +204 -0
  50. package/extensions/factory-provider/scripts/audit-reasoning-efforts.py +84 -0
  51. package/extensions/firecrawl-web/README.md +31 -0
  52. package/extensions/firecrawl-web/auth.ts +92 -0
  53. package/extensions/firecrawl-web/client.ts +238 -0
  54. package/extensions/firecrawl-web/index.ts +96 -0
  55. package/extensions/firecrawl-web/output.ts +125 -0
  56. package/extensions/git-info/README.md +25 -0
  57. package/extensions/git-info/index.ts +162 -0
  58. package/extensions/git-info/src/git.ts +206 -0
  59. package/extensions/git-info/src/ui.ts +291 -0
  60. package/extensions/goal/README.md +44 -0
  61. package/extensions/goal/constants.ts +4 -0
  62. package/extensions/goal/extension.ts +1064 -0
  63. package/extensions/goal/index.ts +2 -0
  64. package/extensions/goal/types.ts +56 -0
  65. package/extensions/goal/ui.ts +334 -0
  66. package/extensions/orchestration/README.md +58 -0
  67. package/extensions/orchestration/dashboard.ts +192 -0
  68. package/extensions/orchestration/engine.ts +706 -0
  69. package/extensions/orchestration/index.ts +243 -0
  70. package/extensions/orchestration/prompts.ts +124 -0
  71. package/extensions/orchestration/protocol.ts +116 -0
  72. package/extensions/orchestration/settings-ui.ts +41 -0
  73. package/extensions/orchestration/settings.ts +59 -0
  74. package/extensions/orchestration/storage.ts +49 -0
  75. package/extensions/orchestration/types.ts +105 -0
  76. package/extensions/performance-status/README.md +5 -0
  77. package/extensions/performance-status/index.ts +171 -0
  78. package/extensions/pi-memory/README.md +53 -0
  79. package/extensions/pi-memory/index.ts +326 -0
  80. package/extensions/pi-memory/src/config.ts +75 -0
  81. package/extensions/pi-memory/src/database.ts +617 -0
  82. package/extensions/pi-memory/src/extraction.ts +178 -0
  83. package/extensions/pi-memory/src/project.ts +80 -0
  84. package/extensions/pi-memory/src/projection.ts +59 -0
  85. package/extensions/pi-memory/src/redaction.ts +60 -0
  86. package/extensions/pi-memory/src/retrieval.ts +30 -0
  87. package/extensions/pi-memory/src/service.ts +194 -0
  88. package/extensions/pi-memory/src/session.ts +146 -0
  89. package/extensions/pi-memory/src/types.ts +82 -0
  90. package/extensions/shared/README.md +18 -0
  91. package/extensions/shared/activity-status.ts +31 -0
  92. package/extensions/shared/child-session.ts +150 -0
  93. package/extensions/shared/context-utilization.ts +47 -0
  94. package/extensions/shared/dashboard-state.ts +99 -0
  95. package/extensions/shared/tool-call-timeout.ts +104 -0
  96. package/extensions/shared/tui-dashboard.ts +139 -0
  97. package/extensions/shell-shortcuts/README.md +17 -0
  98. package/extensions/shell-shortcuts/features/exit-alias.ts +10 -0
  99. package/extensions/shell-shortcuts/index.ts +6 -0
  100. package/extensions/subagents/README.md +89 -0
  101. package/extensions/subagents/index.ts +1386 -0
  102. package/extensions/subagents/src/backend.ts +69 -0
  103. package/extensions/subagents/src/backends/pi.ts +781 -0
  104. package/extensions/subagents/src/catalog.ts +85 -0
  105. package/extensions/subagents/src/config.ts +241 -0
  106. package/extensions/subagents/src/context.ts +57 -0
  107. package/extensions/subagents/src/coordinator.ts +64 -0
  108. package/extensions/subagents/src/domain.ts +294 -0
  109. package/extensions/subagents/src/format.ts +74 -0
  110. package/extensions/subagents/src/manager.ts +813 -0
  111. package/extensions/subagents/src/prompt.ts +94 -0
  112. package/extensions/subagents/src/result-delivery.ts +20 -0
  113. package/extensions/subagents/src/runtime.ts +48 -0
  114. package/extensions/subagents/src/ui/takeover.ts +695 -0
  115. package/extensions/subagents/src/ui/transcript.ts +182 -0
  116. package/extensions/subagents/src/worktree.ts +175 -0
  117. package/extensions/web-fetch/README.md +13 -0
  118. package/extensions/web-fetch/index.ts +441 -0
  119. package/package.json +117 -0
  120. package/skills/background-terminals/SKILL.md +42 -0
  121. package/skills/orchestration/SKILL.md +33 -0
  122. package/skills/subagents/SKILL.md +89 -0
  123. package/themes/ember-warm-dark.json +85 -0
@@ -0,0 +1,72 @@
1
+ import {
2
+ copyToClipboard,
3
+ type ExtensionAPI,
4
+ } from "@earendil-works/pi-coding-agent";
5
+
6
+ export function textFromMessageContent(content: unknown): string {
7
+ if (typeof content === "string") return content.trim();
8
+ if (!Array.isArray(content)) return "";
9
+ return content
10
+ .map((block) => {
11
+ if (!block || typeof block !== "object" || !("type" in block)) return "";
12
+ if (
13
+ block.type === "text" &&
14
+ "text" in block &&
15
+ typeof block.text === "string"
16
+ ) {
17
+ return block.text;
18
+ }
19
+ if (block.type === "image") return "[image]";
20
+ return "";
21
+ })
22
+ .filter(Boolean)
23
+ .join("\n")
24
+ .trim();
25
+ }
26
+
27
+ export function formatConversation(
28
+ messages: ReadonlyArray<{ role?: unknown; content?: unknown }>,
29
+ ): string {
30
+ return messages
31
+ .filter(
32
+ (message) => message.role === "user" || message.role === "assistant",
33
+ )
34
+ .map((message) => ({
35
+ role: String(message.role).toUpperCase(),
36
+ text: textFromMessageContent(message.content),
37
+ }))
38
+ .filter((message) => message.text)
39
+ .map((message) => `${message.role}:\n${message.text}`)
40
+ .join("\n\n---\n\n");
41
+ }
42
+
43
+ export default function copyAllExtension(pi: ExtensionAPI) {
44
+ pi.registerCommand("copy-all", {
45
+ description: "Copy visible user and assistant text from the current branch",
46
+ handler: async (_args, ctx) => {
47
+ await ctx.waitForIdle();
48
+ const messages = ctx.sessionManager
49
+ .getBranch()
50
+ .filter((entry) => entry.type === "message")
51
+ .map((entry) => entry.message);
52
+ const visibleMessages = messages.filter(
53
+ (message) => message.role === "user" || message.role === "assistant",
54
+ );
55
+ const transcript = formatConversation(visibleMessages);
56
+ if (!transcript) {
57
+ ctx.ui.notify("No user or assistant messages to copy", "info");
58
+ return;
59
+ }
60
+ try {
61
+ await copyToClipboard(transcript);
62
+ } catch (error) {
63
+ ctx.ui.notify(
64
+ `Could not copy the conversation: ${error instanceof Error ? error.message : String(error)}`,
65
+ "error",
66
+ );
67
+ return;
68
+ }
69
+ ctx.ui.notify(`Copied ${visibleMessages.length} branch messages`, "info");
70
+ },
71
+ });
72
+ }
@@ -0,0 +1,17 @@
1
+ # Factory API keys
2
+
3
+ Factory API keys are an authentication method of the single `factory` provider; they are not a separate provider or duplicate model catalog.
4
+
5
+ Configure rotating keys in:
6
+
7
+ ```text
8
+ <agent-dir>/factory/api-keys.json
9
+ ```
10
+
11
+ Then run `/login factory` and select **Factory API keys — use configured keys**. Pi stores a non-secret selector while the extension keeps keys in the permission-restricted JSON file. Rotation filters keys through the selected model pool's monthly → weekly → 5-hour availability waterfall, chooses the least recently used eligible key, and applies error-specific cooldown/failover behavior.
12
+
13
+ Alternatively choose Pi's top-level **Use an API key** authentication method to store one key through normal credential storage.
14
+
15
+ Use `/logout` to remove the active Factory authentication selection. The configured key file is intentionally not deleted by logout.
16
+
17
+ Open `/factory` to inspect every account, its Standard/Core usage, and rotation status. For a smoke test, use the current `factory/kimi-k3` model.
@@ -0,0 +1,15 @@
1
+ # Factory authentication
2
+
3
+ Provider ID: `factory`
4
+
5
+ Use one login entry for every authentication method:
6
+
7
+ ```text
8
+ /login factory
9
+ ```
10
+
11
+ Choose Pi's **Use a subscription** path for account import, browser/device login, or the configured rotating-key selector. Choose Pi's native **Use an API key** path to enter one key directly. The chosen credential is stored under `factory`, so it appears once in `/logout`.
12
+
13
+ OAuth account credentials refresh through WorkOS. Configured API-key mode stores only a non-secret selector in Pi auth; actual keys remain in the permission-restricted `<agent-dir>/factory/api-keys.json`. Direct API-key mode stores the key through Pi's normal credential storage.
14
+
15
+ To switch methods, run `/login factory` again. To disable the selected method, use `/logout` and choose Factory.
@@ -0,0 +1,90 @@
1
+ # Unified Factory provider for Pi
2
+
3
+ This package module exposes exactly one Pi provider:
4
+
5
+ ```text
6
+ factory/<model-id>
7
+ ```
8
+
9
+ ## Requirements and installation
10
+
11
+ Use Pi 0.83.0 or newer. Factory access requires either a Factory account or API key. The deterministic catalog and fallback client identity track Droid CLI 0.200.0; an installed Droid CLI can refresh machine-local version and model metadata but is not bundled with this extension.
12
+
13
+ Install it through the private suite package, then restart Pi or run `/reload` and authenticate with `/login factory`. Verify installation without making a model request:
14
+
15
+ ```bash
16
+ pi --list-models factory
17
+ ```
18
+
19
+ When replacing an existing installation, preserve machine-local credential state. Never copy, overwrite, or share Pi auth storage, `~/.factory/`, or the Factory API-key file. Caches and `node_modules` are not portable installation artifacts.
20
+
21
+ ## Authentication
22
+
23
+ Run:
24
+
25
+ ```text
26
+ /login factory
27
+ ```
28
+
29
+ Pi's single Factory login entry offers **Use a subscription** or **Use an API key**. Subscription login then offers:
30
+
31
+ 1. Import the existing Droid CLI Factory account from `~/.factory`.
32
+ 2. Factory browser/device account login.
33
+ 3. Use the rotating API keys already configured in `<agent-dir>/factory/api-keys.json` through a non-secret selector.
34
+
35
+ Use Pi's native **Use an API key** option to enter and store one Factory API key directly.
36
+
37
+ Pi stores the selected authentication method under the single `factory` provider. Consequently `/logout` shows one Factory entry and removes whichever Factory credential is active. Switching authentication method means running `/login factory` again; the model catalog does not change.
38
+
39
+ Configured multi-key mode rotates least-recently-used eligible keys and applies error-specific cooldowns. Eligibility is a billing-pool waterfall: monthly, weekly, and 5-hour windows must all be available for the selected Standard or Droid Core model. Direct API-key and OAuth requests share the same transport/model catalog while applying the appropriate organization-header behavior automatically.
40
+
41
+ ## Models
42
+
43
+ The extension loads one curated catalog from the installed Droid metadata and `factory/models.ts`. Examples:
44
+
45
+ - `factory/gpt-5.6-luna`
46
+ - `factory/gpt-5.6-sol`
47
+ - `factory/claude-sonnet-5`
48
+ - `factory/grok-4.6`
49
+ - `factory/deepseek-v4-flash-0731`
50
+ - `factory/deepseek-v4-pro`
51
+ - `factory/glm-5.2`
52
+ - `factory/kimi-k3`
53
+
54
+ There are no `-oauth` or `-api-key` model duplicates. The user-curated catalog excludes every `-fast` variant and the explicit removals documented in `factory/models.ts`. The current Gemini Pro, MiniMax M3, Nemotron 3 Ultra, and Inkling entries remain hidden; reconsider each family only after its vendor releases a newer generation/model.
55
+
56
+ ## Factory dashboard
57
+
58
+ ```text
59
+ /factory
60
+ ```
61
+
62
+ `/factory` opens a full-width account dashboard combining provider status, authentication, Droid/model metadata, rotation cooldowns, and separate Standard and Droid Core usage for every credential. Percentages are explicitly labeled as **used**. Navigate with the arrow keys or `j`/`k`, press `r` to force-refresh every account, and press Escape to close.
63
+
64
+ Usage is never estimated from Pi token counts: Factory's API already applies model multipliers and cache-hit discounts. Cached records refresh at most every 15 minutes during normal sessions and after Factory runs; the manual command is the explicit force-refresh path.
65
+
66
+ Configured rotating API keys remain separate. Each label gets its own Standard and Core record, and the extension never sums or averages them. Fresh cached exhaustion skips only that credential for the relevant model pool. Monthly exhaustion makes weekly and 5-hour availability irrelevant; weekly exhaustion makes 5-hour availability irrelevant. Among keys that pass the complete waterfall, least-recently-used ordering distributes traffic. Recognized pre-output authorization, rate, quota, billing, or exhaustion errors cool down that key and retry the next eligible key in the same request. Expired windows do not block a key.
67
+
68
+ ## Required request behavior
69
+
70
+ Factory requests use:
71
+
72
+ - `X-Factory-Client: cli`
73
+ - `X-Client-Version: <detected Droid version>`
74
+ - `User-Agent: factory-cli/<version>`
75
+ - OAuth: bearer token plus active Factory organization
76
+ - API key: bearer API key without OAuth-only organization metadata
77
+
78
+ The transport also sanitizes the Factory-blocked Pi identity phrase before sending requests.
79
+
80
+ ## Maintenance and validation
81
+
82
+ See `REFRESH_MODELS.md` and `UPDATING.md` for catalog/client updates. After updating Droid, refresh its cached metadata explicitly:
83
+
84
+ ```bash
85
+ FACTORY_DROID_REFRESH=1 pi --list-models factory
86
+ ```
87
+
88
+ Normal Pi startup and `/reload` do not invoke Droid. After extension changes, run `/reload`, then `/login factory` if no unified credential is stored.
89
+
90
+ From the repository root, run `npm run validate` to typecheck and test this extension with the complete suite.
@@ -0,0 +1,185 @@
1
+ # Refreshing Factory/Droid models and capabilities
2
+
3
+ Normal Pi startup/reload must stay fast and deterministic. The runtime extension should not inspect the Droid binary, call `droid exec --help`, or probe Factory endpoints on every load.
4
+
5
+ Use this guide only when you explicitly want to refresh the local Factory catalog after Droid/Factory changes.
6
+
7
+ ## When to refresh
8
+
9
+ Refresh when one of these happens:
10
+
11
+ - Factory adds/removes models.
12
+ - Droid updates and `droid exec --help` shows a changed model list.
13
+ - A model starts failing because its endpoint family changed.
14
+ - Context windows, max output tokens, image/PDF support, or reasoning levels change.
15
+ - Factory changes required headers or client-version behavior.
16
+
17
+ ## Current runtime source of truth
18
+
19
+ The extension currently reads deterministic local code at startup:
20
+
21
+ - `factory/models.ts` — model catalog, capabilities, endpoint family routing.
22
+ - `factory/constants.ts` — Factory/WorkOS constants and Droid fallback version.
23
+ - `factory/responses.ts` — per-family routing and request compatibility fixes.
24
+
25
+ Normal `/reload` should not run Droid.
26
+
27
+ ## Manual refresh checklist
28
+
29
+ When you ask to refresh models, inspect the installed Droid binary/CLI locally and update the deterministic catalog.
30
+
31
+ ### 1. Check Droid version and help output
32
+
33
+ ```bash
34
+ which droid
35
+ droid --version
36
+ droid exec --help
37
+ ```
38
+
39
+ Capture:
40
+
41
+ - model IDs
42
+ - display names
43
+ - default model
44
+ - reasoning support/defaults from `Model details`
45
+ - deprecated markers
46
+
47
+ ### 2. Inspect embedded registry for capabilities
48
+
49
+ Use binary strings around the model registry instead of guessing:
50
+
51
+ ```bash
52
+ DROID_BIN="$(command -v droid)" python3 - <<'PY'
53
+ import os
54
+ from pathlib import Path
55
+ s = Path(os.environ['DROID_BIN']).read_bytes().decode('utf-8', 'ignore')
56
+ for model in [
57
+ 'gpt-5.6-sol',
58
+ 'claude-opus-5',
59
+ 'gemini-3.1-pro-preview',
60
+ 'gemini-3.7-flash',
61
+ 'grok-4.6',
62
+ 'minimax-m3',
63
+ 'glm-5.2-fast',
64
+ 'kimi-k3',
65
+ 'inkling',
66
+ 'glm-5.2',
67
+ 'deepseek-v4-flash-0731',
68
+ 'deepseek-v4-pro',
69
+ ]:
70
+ pat = f'"{model}":{{id:"{model}"'
71
+ i = s.find(pat)
72
+ print('\n###', model, i)
73
+ if i != -1:
74
+ j = s.find('},"', i + len(pat))
75
+ print(s[i:j+1].replace('\x00', ' ')[:2000])
76
+ PY
77
+ ```
78
+
79
+ Look for fields like:
80
+
81
+ - `contextLimits`
82
+ - `maxInputTokens`
83
+ - `maxOutputTokens`
84
+ - `images`
85
+ - `pdf`
86
+ - `apiProviders`
87
+ - `apiModelProvider`
88
+ - `reasoningEffort`
89
+ - `baseVariant`
90
+ - `availableInCLI`
91
+ - `deprecation`
92
+
93
+ ### 3. Check helper constants in the binary
94
+
95
+ Some models point at shared helper variables. Inspect those too:
96
+
97
+ ```bash
98
+ DROID_BIN="$(command -v droid)" python3 - <<'PY'
99
+ import os
100
+ from pathlib import Path
101
+ s = Path(os.environ['DROID_BIN']).read_bytes().decode('utf-8', 'ignore')
102
+ for name in ['zuT=', 'zNr=', 'YNr=', 'PTT=', 'aiA=', 'S4T=']:
103
+ i = s.find(name)
104
+ print('\n', name, i)
105
+ if i != -1:
106
+ print(s[i-300:i+600].replace('\x00', ' '))
107
+ PY
108
+ ```
109
+
110
+ ### 4. Update deterministic catalog
111
+
112
+ Edit:
113
+
114
+ ```text
115
+ extensions/factory-provider/factory/models.ts
116
+ ```
117
+
118
+ Update:
119
+
120
+ - `BINARY_CAPABILITIES`
121
+ - `FALLBACK_REASONING`
122
+ - `familyForModel()` if endpoint family changes
123
+ - `toPiModel()` only if Pi model shape needs adjustment
124
+
125
+ Preserve the user-curated visibility policy during every refresh:
126
+
127
+ - Never expose model IDs ending in `-fast`.
128
+ - Keep Haiku 4.5, Opus 5, Gemini 3.1 Pro Preview, GLM 5.2 Fast, Inkling, MiniMax M3, and Nemotron 3 Ultra hidden.
129
+ - Do not restore the current Gemini Pro, MiniMax M3, Nemotron 3 Ultra, or Inkling entries. Reconsider each family only after its vendor releases a newer generation/model.
130
+ - A model reappearing in Droid metadata is not authorization to publish it in Pi.
131
+
132
+ Endpoint family routing currently means:
133
+
134
+ - GPT family: `openai-responses` via `https://api.factory.ai/api/llm/o/v1`
135
+ - Kimi / GLM / DeepSeek / Nemotron: `openai-completions` via `https://api.factory.ai/api/llm/o/v1`
136
+ - Claude / MiniMax: `anthropic-messages` via `https://api.factory.ai/api/llm/a`
137
+ - Gemini: custom Factory Gemini route `https://api.factory.ai/api/llm/g/v1/generate`
138
+
139
+ ### 5. Update constants only if changed
140
+
141
+ Edit:
142
+
143
+ ```text
144
+ extensions/factory-provider/factory/constants.ts
145
+ ```
146
+
147
+ Check/update:
148
+
149
+ - `FACTORY_CLIENT_PROTOCOL`
150
+ - `FALLBACK_DROID_VERSION`
151
+ - `FACTORY_API_BASE_URL`
152
+ - `WORKOS_BASE_URL`
153
+ - `WORKOS_CLIENT_ID`
154
+
155
+ ### 6. Validate locally
156
+
157
+ Typecheck:
158
+
159
+ ```bash
160
+ npx --yes -p typescript tsc --noEmit -p /tmp/factory-tsconfig.json
161
+ ```
162
+
163
+ Then test representative non-fast models only:
164
+
165
+ ```bash
166
+ PI_OFFLINE=1 pi -p --no-tools --no-context-files --no-skills --no-prompt-templates --model factory/gpt-5.6-sol 'Reply with exactly: OK'
167
+ PI_OFFLINE=1 pi -p --no-tools --no-context-files --no-skills --no-prompt-templates --model factory/claude-sonnet-5 'Reply with exactly: OK'
168
+ PI_OFFLINE=1 pi -p --no-tools --no-context-files --no-skills --no-prompt-templates --model factory/gemini-3.7-flash 'Reply with exactly: OK'
169
+ PI_OFFLINE=1 pi -p --no-tools --no-context-files --no-skills --no-prompt-templates --model factory/kimi-k3 'Reply with exactly: OK'
170
+ PI_OFFLINE=1 pi -p --no-tools --no-context-files --no-skills --no-prompt-templates --model factory/glm-5.2 'Reply with exactly: OK'
171
+ ```
172
+
173
+ Avoid fast variants unless specifically debugging them to reduce spend.
174
+
175
+ ## Known gotchas
176
+
177
+ - Do not run Droid inspection during normal extension load.
178
+ - OAuth requests require `X-Factory-Org-Id` and organization-scoped token refreshes include `organization_id`; direct API-key requests use their own account scope without OAuth-only organization metadata.
179
+ - Factory may block specific Pi system-prompt phrases; compatibility fixes live in `factory/responses.ts`.
180
+ - Factory Anthropic currently rejects system prompts on this OAuth path; `factory/responses.ts` omits Pi's system prompt for Anthropic-family models.
181
+ - Some Factory models use OpenAI Chat rather than Responses even though they are under the same `/api/llm/o/v1` base.
182
+ - Droid 0.200.0 embeds a conservative 262,144/65,536 Kimi K3 proxy limit; the deterministic catalog intentionally uses Kimi's documented 1,048,576 context and 131,072 default completion limit.
183
+ - Explicitly approved feature-gated models are merged from the deterministic fallback catalog when Droid omits them from help. Catalog visibility does not bypass Factory account/org entitlement; gated endpoints may still reject live requests.
184
+ - Core-model `fireworks`/`baseten` overrides are selected per model from current OpenRouter throughput, latency, uptime, and context data; re-check them when Droid or provider telemetry changes.
185
+ - Gemini uses Factory's custom `/api/llm/g/v1/generate` shape, not the standard Google SDK URL layout.
@@ -0,0 +1,97 @@
1
+ # Updating Factory Droid OAuth provider
2
+
3
+ ## Routine update flow
4
+
5
+ Factory's model list and required client version should follow the installed Droid CLI.
6
+
7
+ ```bash
8
+ droid --version
9
+ droid exec --help
10
+ ```
11
+
12
+ Refresh the deterministic Droid cache explicitly, then reload Pi:
13
+
14
+ ```bash
15
+ FACTORY_DROID_REFRESH=1 pi --list-models factory
16
+ ```
17
+
18
+ ```text
19
+ /reload
20
+ ```
21
+
22
+ Normal startup and reload do not invoke Droid; they use the refreshed cache or deterministic fallback catalog.
23
+
24
+ ## Files to update manually if needed
25
+
26
+ - `factory/constants.ts`
27
+ - `FACTORY_CLIENT_PROTOCOL`
28
+ - `FALLBACK_DROID_VERSION`
29
+ - WorkOS/API base URLs if Factory changes them.
30
+ - `factory/models.ts`
31
+ - `parseModelsFromDroidHelp()` if Droid help formatting changes.
32
+ - `BINARY_CAPABILITIES` for context window, max output tokens, image support, and PDF support.
33
+ - `DROID_MODELS_FALLBACK` if parser fails or Droid is unavailable.
34
+ - `factory/auth.ts`
35
+ - WorkOS device/refresh flow and Droid encrypted auth import.
36
+
37
+ ## Updating Droid
38
+
39
+ Try Droid's updater first:
40
+
41
+ ```bash
42
+ droid update
43
+ ```
44
+
45
+ If unavailable, reinstall via Factory's current installer:
46
+
47
+ ```bash
48
+ curl -fsSL https://app.factory.ai/cli | sh
49
+ ```
50
+
51
+ Then verify:
52
+
53
+ ```bash
54
+ which droid
55
+ droid --version
56
+ droid exec --help
57
+ ```
58
+
59
+ ## Binary inspection checklist
60
+
61
+ If Factory changes endpoints or headers, inspect the installed binary locally:
62
+
63
+ ```bash
64
+ strings "$(which droid)" | rg 'api/llm/o/v1|X-Factory-Client|X-Client-Version|workos|authorize/device|client_01HNM'
65
+ ```
66
+
67
+ Known current values:
68
+
69
+ - Model registry values are embedded near the Droid binary strings for `$o={...}` with fields like `contextLimits`, `images`, and `pdf`.
70
+ - Examples verified through Droid 0.200.0:
71
+ - Gemini 3.7 Flash: `maxInputTokens: 1000000`, `maxOutputTokens: 65536`, PDF and image input enabled, with `low`, `medium`, and `high` reasoning.
72
+ - Inkling: `maxInputTokens: 1040000`, `maxOutputTokens: 32768`, images enabled, PDF disabled, Fireworks and Baseten routes.
73
+ - DeepSeek V4 Flash 0731: `maxInputTokens: 1040000`, `maxOutputTokens: 131072`, images/PDF disabled, Fireworks route.
74
+ - Claude Opus 4.8: `contextLimits: zuT` => `maxInputTokens: 867000`, `maxOutputTokens: 128000`, `pdf: true`, images enabled.
75
+ - Claude Sonnet 4.6: `maxInputTokens: 931000`, `maxOutputTokens: 64000`.
76
+ - GPT-5.6/GPT-5.5 Pro: `maxInputTokens: 1050000`, `maxOutputTokens: 128000`.
77
+ - Grok 4.6: `maxInputTokens: 200000`, `maxOutputTokens: 63356`, images enabled, PDF disabled.
78
+ - MiniMax M3: `maxInputTokens: 512000`, `maxOutputTokens: 64000`, images enabled, PDF disabled.
79
+ - GLM-5.2: `maxInputTokens: 1040000`, `maxOutputTokens: 131072`, no images/PDF.
80
+ - GLM-5.2 Fast: `maxInputTokens: 524288`, `maxOutputTokens: 131072`, no images/PDF.
81
+ - DeepSeek V4 Pro: `maxInputTokens: 1040000`, `maxOutputTokens: 65536`, no images/PDF.
82
+ - Responses base: `https://api.factory.ai/api/llm/o/v1`
83
+ - Required headers:
84
+ - `X-Factory-Client: cli`
85
+ - `X-Client-Version: <droid --version>`
86
+ - WorkOS base: `https://api.workos.com/user_management`
87
+ - Production WorkOS client ID: `client_01HNM792M5G5G1A2THWPXKFMXB`
88
+
89
+ ## Smoke test after updates
90
+
91
+ 1. `/reload`
92
+ 2. `/login factory` if not logged in.
93
+ 3. Run `/factory`.
94
+ 4. Confirm every configured credential appears in the dashboard with separately labeled Standard and Droid Core usage.
95
+ 5. Send a tiny prompt with `factory/gpt-5.6-sol` or another known model.
96
+
97
+ If Factory responds with `Unable to determine client version`, inspect/update `FACTORY_CLIENT_PROTOCOL` or Droid version detection.