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.
- package/LICENSE +21 -0
- package/README.md +94 -0
- package/THIRD_PARTY_NOTICES.md +11 -0
- package/docs/ARCHITECTURE.md +54 -0
- package/docs/DEVELOPMENT.md +88 -0
- package/docs/EXTENSIONS.md +89 -0
- package/extensions/antigravity-provider/LICENSE +21 -0
- package/extensions/antigravity-provider/README.md +23 -0
- package/extensions/antigravity-provider/antigravity/cloud-code-assist.ts +519 -0
- package/extensions/antigravity-provider/antigravity/index.ts +67 -0
- package/extensions/antigravity-provider/antigravity/models.ts +184 -0
- package/extensions/antigravity-provider/antigravity/oauth.ts +499 -0
- package/extensions/antigravity-provider/index.ts +3 -0
- package/extensions/ask-user/README.md +21 -0
- package/extensions/ask-user/index.ts +417 -0
- package/extensions/background-terminals/README.md +43 -0
- package/extensions/background-terminals/index.ts +400 -0
- package/extensions/background-terminals/src/manager.ts +480 -0
- package/extensions/background-terminals/src/output-buffer.ts +110 -0
- package/extensions/background-terminals/src/presentation.ts +74 -0
- package/extensions/background-terminals/src/types.ts +47 -0
- package/extensions/background-terminals/src/ui.ts +478 -0
- package/extensions/context-usage/LICENSE +21 -0
- package/extensions/context-usage/README.md +20 -0
- package/extensions/context-usage/index.ts +2006 -0
- package/extensions/context-usage/lib/ansi.ts +60 -0
- package/extensions/context-usage/lib/boundary.ts +27 -0
- package/extensions/context-usage/lib/chat.ts +190 -0
- package/extensions/context-usage/lib/config.ts +30 -0
- package/extensions/context-usage/lib/fmt.ts +59 -0
- package/extensions/context-usage/lib/style.ts +260 -0
- package/extensions/copy-all/README.md +15 -0
- package/extensions/copy-all/index.ts +72 -0
- package/extensions/factory-provider/API_KEYS.md +17 -0
- package/extensions/factory-provider/AUTH.md +15 -0
- package/extensions/factory-provider/README.md +90 -0
- package/extensions/factory-provider/REFRESH_MODELS.md +185 -0
- package/extensions/factory-provider/UPDATING.md +97 -0
- package/extensions/factory-provider/factory/api-keys.ts +407 -0
- package/extensions/factory-provider/factory/auth.ts +132 -0
- package/extensions/factory-provider/factory/constants.ts +15 -0
- package/extensions/factory-provider/factory/dashboard.ts +363 -0
- package/extensions/factory-provider/factory/droid.ts +84 -0
- package/extensions/factory-provider/factory/limits.ts +342 -0
- package/extensions/factory-provider/factory/models.ts +283 -0
- package/extensions/factory-provider/factory/responses.ts +331 -0
- package/extensions/factory-provider/factory/warm-theme.ts +53 -0
- package/extensions/factory-provider/factory/websocket.ts +130 -0
- package/extensions/factory-provider/index.ts +204 -0
- package/extensions/factory-provider/scripts/audit-reasoning-efforts.py +84 -0
- package/extensions/firecrawl-web/README.md +31 -0
- package/extensions/firecrawl-web/auth.ts +92 -0
- package/extensions/firecrawl-web/client.ts +238 -0
- package/extensions/firecrawl-web/index.ts +96 -0
- package/extensions/firecrawl-web/output.ts +125 -0
- package/extensions/git-info/README.md +25 -0
- package/extensions/git-info/index.ts +162 -0
- package/extensions/git-info/src/git.ts +206 -0
- package/extensions/git-info/src/ui.ts +291 -0
- package/extensions/goal/README.md +44 -0
- package/extensions/goal/constants.ts +4 -0
- package/extensions/goal/extension.ts +1064 -0
- package/extensions/goal/index.ts +2 -0
- package/extensions/goal/types.ts +56 -0
- package/extensions/goal/ui.ts +334 -0
- package/extensions/orchestration/README.md +58 -0
- package/extensions/orchestration/dashboard.ts +192 -0
- package/extensions/orchestration/engine.ts +706 -0
- package/extensions/orchestration/index.ts +243 -0
- package/extensions/orchestration/prompts.ts +124 -0
- package/extensions/orchestration/protocol.ts +116 -0
- package/extensions/orchestration/settings-ui.ts +41 -0
- package/extensions/orchestration/settings.ts +59 -0
- package/extensions/orchestration/storage.ts +49 -0
- package/extensions/orchestration/types.ts +105 -0
- package/extensions/performance-status/README.md +5 -0
- package/extensions/performance-status/index.ts +171 -0
- package/extensions/pi-memory/README.md +53 -0
- package/extensions/pi-memory/index.ts +326 -0
- package/extensions/pi-memory/src/config.ts +75 -0
- package/extensions/pi-memory/src/database.ts +617 -0
- package/extensions/pi-memory/src/extraction.ts +178 -0
- package/extensions/pi-memory/src/project.ts +80 -0
- package/extensions/pi-memory/src/projection.ts +59 -0
- package/extensions/pi-memory/src/redaction.ts +60 -0
- package/extensions/pi-memory/src/retrieval.ts +30 -0
- package/extensions/pi-memory/src/service.ts +194 -0
- package/extensions/pi-memory/src/session.ts +146 -0
- package/extensions/pi-memory/src/types.ts +82 -0
- package/extensions/shared/README.md +18 -0
- package/extensions/shared/activity-status.ts +31 -0
- package/extensions/shared/child-session.ts +150 -0
- package/extensions/shared/context-utilization.ts +47 -0
- package/extensions/shared/dashboard-state.ts +99 -0
- package/extensions/shared/tool-call-timeout.ts +104 -0
- package/extensions/shared/tui-dashboard.ts +139 -0
- package/extensions/shell-shortcuts/README.md +17 -0
- package/extensions/shell-shortcuts/features/exit-alias.ts +10 -0
- package/extensions/shell-shortcuts/index.ts +6 -0
- package/extensions/subagents/README.md +89 -0
- package/extensions/subagents/index.ts +1386 -0
- package/extensions/subagents/src/backend.ts +69 -0
- package/extensions/subagents/src/backends/pi.ts +781 -0
- package/extensions/subagents/src/catalog.ts +85 -0
- package/extensions/subagents/src/config.ts +241 -0
- package/extensions/subagents/src/context.ts +57 -0
- package/extensions/subagents/src/coordinator.ts +64 -0
- package/extensions/subagents/src/domain.ts +294 -0
- package/extensions/subagents/src/format.ts +74 -0
- package/extensions/subagents/src/manager.ts +813 -0
- package/extensions/subagents/src/prompt.ts +94 -0
- package/extensions/subagents/src/result-delivery.ts +20 -0
- package/extensions/subagents/src/runtime.ts +48 -0
- package/extensions/subagents/src/ui/takeover.ts +695 -0
- package/extensions/subagents/src/ui/transcript.ts +182 -0
- package/extensions/subagents/src/worktree.ts +175 -0
- package/extensions/web-fetch/README.md +13 -0
- package/extensions/web-fetch/index.ts +441 -0
- package/package.json +117 -0
- package/skills/background-terminals/SKILL.md +42 -0
- package/skills/orchestration/SKILL.md +33 -0
- package/skills/subagents/SKILL.md +89 -0
- 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.
|