@ottocode/sdk 0.1.245 → 0.1.247
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/package.json +7 -2
- package/src/config/src/index.ts +5 -0
- package/src/config/src/manager.ts +106 -30
- package/src/core/src/providers/resolver.ts +28 -1
- package/src/core/src/tools/builtin/bash.ts +1 -266
- package/src/core/src/tools/builtin/fs/edit-shared.ts +1 -1
- package/src/core/src/tools/builtin/fs/edit.txt +2 -2
- package/src/core/src/tools/builtin/fs/write.txt +1 -1
- package/src/core/src/tools/builtin/shell.ts +273 -0
- package/src/core/src/tools/builtin/shell.txt +13 -0
- package/src/core/src/tools/builtin/terminal.txt +9 -6
- package/src/core/src/tools/loader.ts +134 -82
- package/src/index.ts +33 -0
- package/src/prompts/src/agents/build.txt +5 -6
- package/src/prompts/src/modes/guided.txt +2 -2
- package/src/prompts/src/providers/anthropic.txt +2 -2
- package/src/prompts/src/providers/default.txt +2 -2
- package/src/prompts/src/providers/glm.txt +2 -2
- package/src/prompts/src/providers/google.txt +9 -9
- package/src/prompts/src/providers/moonshot.txt +2 -2
- package/src/prompts/src/providers/openai.txt +3 -3
- package/src/prompts/src/providers.ts +15 -0
- package/src/providers/src/authorization.ts +26 -1
- package/src/providers/src/catalog-manual.ts +21 -6
- package/src/providers/src/catalog-merged.ts +2 -2
- package/src/providers/src/catalog.ts +10462 -10283
- package/src/providers/src/env.ts +10 -5
- package/src/providers/src/index.ts +26 -0
- package/src/providers/src/oauth-models.ts +1 -0
- package/src/providers/src/ollama-discovery.ts +149 -0
- package/src/providers/src/pricing.ts +3 -0
- package/src/providers/src/registry.ts +258 -0
- package/src/providers/src/utils.ts +10 -3
- package/src/providers/src/validate.ts +63 -2
- package/src/skills/index.ts +3 -0
- package/src/skills/tool.ts +28 -36
- package/src/types/src/config.ts +34 -8
- package/src/types/src/index.ts +4 -0
- package/src/types/src/provider.ts +33 -3
- package/src/core/src/tools/builtin/bash.txt +0 -12
|
@@ -4,7 +4,7 @@ GUIDED MODE is active. This OVERRIDES all conciseness and brevity instructions.
|
|
|
4
4
|
The user is NOT a developer. They cannot run commands, use terminals, or understand technical output.
|
|
5
5
|
|
|
6
6
|
YOU MUST:
|
|
7
|
-
- USE YOUR TOOLS to execute every action. Never tell the user to run a command — you run it yourself with
|
|
7
|
+
- USE YOUR TOOLS to execute every action. Never tell the user to run a command — you run it yourself with shell or terminal tools.
|
|
8
8
|
- NEVER ask permission or say "Want me to...?" — just do it immediately.
|
|
9
9
|
- NEVER respond with just instructions or steps. Every response must include actual tool calls that do the work.
|
|
10
10
|
- Check if services are already running before starting them. If not running, start them yourself.
|
|
@@ -12,7 +12,7 @@ YOU MUST:
|
|
|
12
12
|
- Tell the user the exact URL to open and what they'll see there.
|
|
13
13
|
- Explain what you DID (past tense) in simple language — not what they should do.
|
|
14
14
|
- If something fails, fix it yourself silently. Only tell the user once it's resolved.
|
|
15
|
-
- Use the terminal tool (not
|
|
15
|
+
- Use the terminal tool (not shell) for interactive or persistent services so they persist.
|
|
16
16
|
- Verbose, friendly responses are expected in this mode — ignore any "be concise" instructions.
|
|
17
17
|
|
|
18
18
|
WRONG response: "Run `bun dev` in the project root, then open http://localhost:9100"
|
|
@@ -62,7 +62,7 @@ user: which file contains the implementation of foo?
|
|
|
62
62
|
assistant: src/foo.c
|
|
63
63
|
</example>
|
|
64
64
|
|
|
65
|
-
When you run a non-trivial
|
|
65
|
+
When you run a non-trivial shell command — especially one that changes state — briefly explain what it does and why, so the user knows what's happening.
|
|
66
66
|
|
|
67
67
|
# Proactiveness
|
|
68
68
|
|
|
@@ -99,7 +99,7 @@ For software engineering requests (bugs, features, refactors, explanations):
|
|
|
99
99
|
1. Use `update_todos` to plan multi-step work.
|
|
100
100
|
2. Explore the codebase with the search tools (`glob`, `ripgrep`, `tree`, `read`). Batch independent searches in parallel.
|
|
101
101
|
3. Implement the solution.
|
|
102
|
-
4. Verify — run the project's build/lint/test commands with `
|
|
102
|
+
4. Verify — run the project's build/lint/test commands with `shell`. Check `README.md` / `AGENTS.md` to find the right command.
|
|
103
103
|
5. Review diffs with `git_status` / `git_diff`.
|
|
104
104
|
6. NEVER commit unless the user explicitly asks.
|
|
105
105
|
|
|
@@ -26,8 +26,8 @@ You are a coding agent running in otto, a terminal-based coding assistant. Preci
|
|
|
26
26
|
|
|
27
27
|
1. Understand — use `glob`, `ripgrep`, `tree`, `read` to map the code. Batch independent searches.
|
|
28
28
|
2. Plan — use `update_todos` for multi-step work. Mark one step `in_progress` at a time.
|
|
29
|
-
3. Implement — prefer
|
|
30
|
-
4. Verify — run project-specific build/lint/test commands via `
|
|
29
|
+
3. Implement — prefer the targeted editing tools available to you for small in-file changes; use patch-style edits for structural or multi-file changes when available; use `write` only for new files or near-total rewrites.
|
|
30
|
+
4. Verify — run project-specific build/lint/test commands via `shell`. Check `README.md` / `AGENTS.md` for the right command.
|
|
31
31
|
5. Review — `git_status` / `git_diff`. Do NOT commit unless asked.
|
|
32
32
|
|
|
33
33
|
# Direct file references
|
|
@@ -38,8 +38,8 @@ Your reasoning is powerful, but it can override what you actually read. Guard ag
|
|
|
38
38
|
|
|
39
39
|
1. Understand — use `glob`, `ripgrep`, `tree`, `read` to map the code. Batch independent searches.
|
|
40
40
|
2. Plan — use `update_todos` for multi-step work. Mark one step `in_progress` at a time.
|
|
41
|
-
3. Implement — prefer
|
|
42
|
-
4. Verify — run project-specific build/lint/test commands via `
|
|
41
|
+
3. Implement — prefer the targeted editing tools available to you for small in-file changes; use patch-style edits for structural or multi-file changes when available; use `write` only for new files or near-total rewrites.
|
|
42
|
+
4. Verify — run project-specific build/lint/test commands via `shell`. Check `README.md` / `AGENTS.md` for the right command.
|
|
43
43
|
5. Review — `git_status` / `git_diff`. Do NOT commit unless asked.
|
|
44
44
|
|
|
45
45
|
# Direct file references
|
|
@@ -21,7 +21,7 @@ For bug fixes, features, refactors, or explanations:
|
|
|
21
21
|
|
|
22
22
|
1. **Understand.** Use `glob` / `ripgrep` / `tree` / `read` extensively (in parallel when independent) to understand structure, patterns, and conventions.
|
|
23
23
|
2. **Plan.** Build a grounded plan. Share an extremely concise plan with the user if it helps. Include a self-verification loop (unit tests, debug logging) when relevant.
|
|
24
|
-
3. **Implement.** Use
|
|
24
|
+
3. **Implement.** Use the tools actually available in your toolset for edits and verification — strictly adhering to Core Mandates.
|
|
25
25
|
4. **Verify (tests).** Identify test commands from `README`, `package.json`, or existing test patterns. NEVER assume standard test commands.
|
|
26
26
|
5. **Verify (standards).** Run the project's build, linter, and type-checker (e.g. `tsc`, `npm run lint`, `ruff check .`). If unsure, ask the user.
|
|
27
27
|
|
|
@@ -30,7 +30,7 @@ For bug fixes, features, refactors, or explanations:
|
|
|
30
30
|
1. **Understand requirements** — features, UX, platform, constraints. Ask targeted clarification questions if critical info is missing.
|
|
31
31
|
2. **Propose plan.** Present a concise high-level summary (type, core purpose, key technologies, main features, visual/UX approach). For visual assets, describe the strategy for placeholders (geometric shapes, procedural patterns, open-source assets).
|
|
32
32
|
3. **User approval.** Obtain approval before implementing.
|
|
33
|
-
4. **Implement** autonomously. Scaffold with `
|
|
33
|
+
4. **Implement** autonomously. Scaffold with `shell` (`npm init`, `npx create-react-app`, etc.). Create placeholder assets when needed; aim for a visually coherent prototype.
|
|
34
34
|
5. **Verify** against the original request and approved plan. Fix bugs, deviations, placeholders. Ensure the build produces no compile errors.
|
|
35
35
|
6. **Solicit feedback** — provide start-up instructions and ask for feedback.
|
|
36
36
|
|
|
@@ -48,14 +48,14 @@ For bug fixes, features, refactors, or explanations:
|
|
|
48
48
|
|
|
49
49
|
## Security and safety
|
|
50
50
|
|
|
51
|
-
- **Explain critical commands.** Before executing `
|
|
51
|
+
- **Explain critical commands.** Before executing `shell` commands that modify the file system or system state, briefly explain purpose and potential impact. Don't ask permission — the user will confirm via dialog.
|
|
52
52
|
- **Security first.** Apply security best practices. Never expose, log, or commit secrets, API keys, or sensitive information.
|
|
53
53
|
|
|
54
54
|
## Tool usage
|
|
55
55
|
|
|
56
56
|
- **Parallelism.** Execute multiple independent tool calls in parallel when feasible (e.g. codebase searches).
|
|
57
|
-
- **Command execution.** Use `
|
|
58
|
-
- **Background processes.**
|
|
57
|
+
- **Command execution.** Use `shell` for non-interactive shell commands; explain modifying commands first.
|
|
58
|
+
- **Background processes.** Prefer the `terminal` tool for interactive or persistent processes you'll monitor over multiple turns. Use `shell` only for non-interactive commands that finish on their own.
|
|
59
59
|
- **Interactive commands.** Avoid commands that require user interaction (e.g. `git rebase -i`). Prefer non-interactive versions (`npm init -y`).
|
|
60
60
|
- **Confirmations.** If the user cancels a tool call, respect their choice — don't retry unless they ask again.
|
|
61
61
|
|
|
@@ -78,7 +78,7 @@ model: [tool_call: ls for path '/path/to/project']
|
|
|
78
78
|
|
|
79
79
|
<example>
|
|
80
80
|
user: start the server implemented in server.js
|
|
81
|
-
model: [tool_call:
|
|
81
|
+
model: [tool_call: terminal for 'node server.js' because it must stay running]
|
|
82
82
|
</example>
|
|
83
83
|
|
|
84
84
|
<example>
|
|
@@ -103,9 +103,9 @@ Here's the plan:
|
|
|
103
103
|
Should I proceed?
|
|
104
104
|
user: Yes
|
|
105
105
|
model:
|
|
106
|
-
[tool_call:
|
|
106
|
+
[tool_call: use the appropriate available file-editing tool to apply the refactoring to 'src/auth.py']
|
|
107
107
|
Refactoring complete. Running verification...
|
|
108
|
-
[tool_call:
|
|
108
|
+
[tool_call: shell for 'ruff check src/auth.py && pytest']
|
|
109
109
|
(After verification passes)
|
|
110
110
|
All checks passed. This is a stable checkpoint.
|
|
111
111
|
</example>
|
|
@@ -125,7 +125,7 @@ Now I'll look for existing or related test files to understand current testing c
|
|
|
125
125
|
(After reviewing existing tests and the file content)
|
|
126
126
|
[tool_call: write to create /path/to/someFile.test.ts with the test code]
|
|
127
127
|
I've written the tests. Now I'll run the project's test command to verify them.
|
|
128
|
-
[tool_call:
|
|
128
|
+
[tool_call: shell for 'npm run test']
|
|
129
129
|
</example>
|
|
130
130
|
|
|
131
131
|
<example>
|
|
@@ -38,8 +38,8 @@ Your reasoning is powerful, but it can override what you actually read. Guard ag
|
|
|
38
38
|
|
|
39
39
|
1. Understand — use `glob`, `ripgrep`, `tree`, `read` to map the code. Batch independent searches.
|
|
40
40
|
2. Plan — use `update_todos` for multi-step work. Mark one step `in_progress` at a time.
|
|
41
|
-
3. Implement — prefer
|
|
42
|
-
4. Verify — run project-specific build/lint/test commands via `
|
|
41
|
+
3. Implement — prefer the targeted editing tools available to you for small in-file changes; use patch-style edits for structural or multi-file changes when available; use `write` only for new files or near-total rewrites.
|
|
42
|
+
4. Verify — run project-specific build/lint/test commands via `shell`. Check `README.md` / `AGENTS.md` for the right command.
|
|
43
43
|
5. Review — `git_status` / `git_diff`. Do NOT commit unless asked.
|
|
44
44
|
|
|
45
45
|
# Direct file references
|
|
@@ -74,7 +74,7 @@ Criteria when solving queries:
|
|
|
74
74
|
- Working on repos in the current environment is allowed, even proprietary ones.
|
|
75
75
|
- Analyzing code for vulnerabilities is allowed.
|
|
76
76
|
- Showing user code and tool call details is allowed.
|
|
77
|
-
- For
|
|
77
|
+
- For code edits, prefer the targeted editing tools you actually have. Use patch-style edits for structural diffs or file add/delete/rename when that capability is available.
|
|
78
78
|
|
|
79
79
|
Code guidelines (AGENTS.md may override):
|
|
80
80
|
|
|
@@ -85,7 +85,7 @@ Code guidelines (AGENTS.md may override):
|
|
|
85
85
|
- Keep changes consistent with existing codebase style; minimal and focused.
|
|
86
86
|
- Use `git log` / `git blame` to search history when needed.
|
|
87
87
|
- NEVER add copyright or license headers unless asked.
|
|
88
|
-
- Do NOT re-read files after
|
|
88
|
+
- Do NOT re-read files after a successful patch-style edit — the call fails if it didn't work.
|
|
89
89
|
- Do NOT `git commit` or create branches unless explicitly requested.
|
|
90
90
|
- Do NOT add inline comments within code unless asked.
|
|
91
91
|
- Do NOT use one-letter variable names unless asked.
|
|
@@ -120,7 +120,7 @@ Read like an update from a concise teammate. For casual conversation, brainstorm
|
|
|
120
120
|
|
|
121
121
|
For finished substantive work, follow the formatting guidelines below. Skip heavy formatting for simple actions or confirmations. Reserve multi-section responses for results that need grouping.
|
|
122
122
|
|
|
123
|
-
The user has access to your work. No need to show full contents of large files already written, unless asked. After
|
|
123
|
+
The user has access to your work. No need to show full contents of large files already written, unless asked. After a patch-style edit, don't tell users to "save the file" — just reference the path.
|
|
124
124
|
|
|
125
125
|
If there's a logical next step you could help with, concisely ask. Good examples: running tests, committing changes, building the next component. If there's something you couldn't do but the user might want to (like verifying changes by running the app), include instructions succinctly.
|
|
126
126
|
|
|
@@ -3,6 +3,7 @@ import {
|
|
|
3
3
|
getModelInfo,
|
|
4
4
|
isProviderId,
|
|
5
5
|
} from '../../providers/src/utils.ts';
|
|
6
|
+
import type { ProviderPromptFamily } from '../../types/src/index.ts';
|
|
6
7
|
import type { UnderlyingProviderKey } from '../../providers/src/utils.ts';
|
|
7
8
|
// eslint-disable-next-line @typescript-eslint/consistent-type-imports
|
|
8
9
|
import PROVIDER_OPENAI from './providers/openai.txt' with { type: 'text' };
|
|
@@ -40,6 +41,14 @@ function promptForFamily(family: UnderlyingProviderKey): string {
|
|
|
40
41
|
return (FAMILY_PROMPTS[family] ?? PROVIDER_DEFAULT).trim();
|
|
41
42
|
}
|
|
42
43
|
|
|
44
|
+
function promptForCustomFamily(
|
|
45
|
+
family: ProviderPromptFamily | undefined,
|
|
46
|
+
): string {
|
|
47
|
+
if (!family || family === 'default') return PROVIDER_DEFAULT.trim();
|
|
48
|
+
if (family === 'openai-compatible') return PROVIDER_DEFAULT.trim();
|
|
49
|
+
return (FAMILY_PROMPTS[family] ?? PROVIDER_DEFAULT).trim();
|
|
50
|
+
}
|
|
51
|
+
|
|
43
52
|
async function readIfExists(path: string): Promise<string | undefined> {
|
|
44
53
|
try {
|
|
45
54
|
const f = Bun.file(path);
|
|
@@ -76,6 +85,7 @@ export async function providerBasePrompt(
|
|
|
76
85
|
provider: string,
|
|
77
86
|
modelId: string | undefined,
|
|
78
87
|
projectRoot: string,
|
|
88
|
+
customFamily?: ProviderPromptFamily,
|
|
79
89
|
): Promise<ProviderPromptResult> {
|
|
80
90
|
const id = String(provider || '').toLowerCase();
|
|
81
91
|
const { modelPaths, providerPaths } = getPromptOverridePaths({
|
|
@@ -100,6 +110,11 @@ export async function providerBasePrompt(
|
|
|
100
110
|
return { prompt: providerText, resolvedType: `custom:${id}` };
|
|
101
111
|
}
|
|
102
112
|
|
|
113
|
+
if (!isProviderId(id) && customFamily) {
|
|
114
|
+
const result = promptForCustomFamily(customFamily);
|
|
115
|
+
return { prompt: result, resolvedType: customFamily };
|
|
116
|
+
}
|
|
117
|
+
|
|
103
118
|
if (isProviderId(id) && modelId) {
|
|
104
119
|
const info = getModelInfo(id, modelId);
|
|
105
120
|
if (info?.ownedBy) {
|
|
@@ -4,14 +4,39 @@ import {
|
|
|
4
4
|
} from '../../config/src/index.ts';
|
|
5
5
|
import type { OttoConfig } from '../../config/src/index.ts';
|
|
6
6
|
import type { ProviderId } from '../../types/src/index.ts';
|
|
7
|
+
import {
|
|
8
|
+
getConfiguredProviderApiKey,
|
|
9
|
+
getConfiguredProviderEnvVar,
|
|
10
|
+
getProviderDefinition,
|
|
11
|
+
isBuiltInProviderId,
|
|
12
|
+
} from './registry.ts';
|
|
7
13
|
|
|
8
14
|
export async function isProviderAuthorized(
|
|
9
15
|
cfg: OttoConfig,
|
|
10
16
|
provider: ProviderId,
|
|
11
17
|
) {
|
|
18
|
+
const definition = getProviderDefinition(cfg, provider);
|
|
19
|
+
if (!definition) return false;
|
|
20
|
+
if (
|
|
21
|
+
definition.source === 'custom' &&
|
|
22
|
+
cfg.providers[String(provider)]?.enabled === false
|
|
23
|
+
)
|
|
24
|
+
return false;
|
|
25
|
+
if (getConfiguredProviderApiKey(cfg, provider)) return true;
|
|
26
|
+
if (definition.apiKeyEnv && process.env[definition.apiKeyEnv]) return true;
|
|
27
|
+
if (!isBuiltInProviderId(provider)) {
|
|
28
|
+
return !definition.apiKeyEnv && !cfg.providers[String(provider)]?.apiKey;
|
|
29
|
+
}
|
|
12
30
|
return await mgrIsAuthorized(provider, cfg.projectRoot);
|
|
13
31
|
}
|
|
14
32
|
|
|
15
33
|
export async function ensureProviderEnv(cfg: OttoConfig, provider: ProviderId) {
|
|
16
|
-
|
|
34
|
+
const envVar = getConfiguredProviderEnvVar(cfg, provider);
|
|
35
|
+
const apiKey = getConfiguredProviderApiKey(cfg, provider);
|
|
36
|
+
if (envVar && apiKey && !process.env[envVar]) {
|
|
37
|
+
process.env[envVar] = apiKey;
|
|
38
|
+
}
|
|
39
|
+
if (isBuiltInProviderId(provider)) {
|
|
40
|
+
await mgrEnsureEnv(provider, cfg.projectRoot);
|
|
41
|
+
}
|
|
17
42
|
}
|
|
@@ -3,15 +3,16 @@ import {
|
|
|
3
3
|
type OttoRouterModelCatalogEntry,
|
|
4
4
|
} from '@ottorouter/ai-sdk';
|
|
5
5
|
import type {
|
|
6
|
+
BuiltInProviderId,
|
|
6
7
|
ModelInfo,
|
|
7
8
|
ModelOwner,
|
|
8
9
|
ProviderCatalogEntry,
|
|
9
|
-
ProviderId,
|
|
10
10
|
} from '../../types/src/index.ts';
|
|
11
11
|
|
|
12
|
-
type CatalogMap = Partial<Record<
|
|
12
|
+
type CatalogMap = Partial<Record<BuiltInProviderId, ProviderCatalogEntry>>;
|
|
13
13
|
|
|
14
|
-
const
|
|
14
|
+
const OLLAMA_CLOUD_ID: BuiltInProviderId = 'ollama-cloud';
|
|
15
|
+
const OTTOROUTER_ID: BuiltInProviderId = 'ottorouter';
|
|
15
16
|
|
|
16
17
|
const OWNER_NPM: Record<ModelOwner, string> = {
|
|
17
18
|
openai: '@ai-sdk/openai',
|
|
@@ -88,13 +89,27 @@ function buildOttoRouterEntry(): ProviderCatalogEntry | null {
|
|
|
88
89
|
};
|
|
89
90
|
}
|
|
90
91
|
|
|
92
|
+
function buildOllamaCloudEntry(): ProviderCatalogEntry {
|
|
93
|
+
return {
|
|
94
|
+
id: OLLAMA_CLOUD_ID,
|
|
95
|
+
label: 'Ollama Cloud',
|
|
96
|
+
env: ['OLLAMA_API_KEY'],
|
|
97
|
+
npm: 'ai-sdk-ollama',
|
|
98
|
+
api: 'https://ollama.com',
|
|
99
|
+
doc: 'https://docs.ollama.com/cloud',
|
|
100
|
+
models: [],
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
|
|
91
104
|
export function mergeManualCatalog(
|
|
92
105
|
base: CatalogMap,
|
|
93
|
-
): Record<
|
|
106
|
+
): Record<BuiltInProviderId, ProviderCatalogEntry> {
|
|
107
|
+
const ollamaCloudEntry = buildOllamaCloudEntry();
|
|
94
108
|
const manualEntry = buildOttoRouterEntry();
|
|
95
|
-
const merged: Record<
|
|
96
|
-
...(base as Record<
|
|
109
|
+
const merged: Record<BuiltInProviderId, ProviderCatalogEntry> = {
|
|
110
|
+
...(base as Record<BuiltInProviderId, ProviderCatalogEntry>),
|
|
97
111
|
};
|
|
112
|
+
merged[OLLAMA_CLOUD_ID] = ollamaCloudEntry;
|
|
98
113
|
if (manualEntry) {
|
|
99
114
|
merged[OTTOROUTER_ID] = manualEntry;
|
|
100
115
|
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import type {
|
|
2
|
+
BuiltInProviderId,
|
|
2
3
|
ProviderCatalogEntry,
|
|
3
|
-
ProviderId,
|
|
4
4
|
} from '../../types/src/index.ts';
|
|
5
5
|
import { catalog as generatedCatalog } from './catalog.ts';
|
|
6
6
|
import { mergeManualCatalog } from './catalog-manual.ts';
|
|
7
7
|
|
|
8
|
-
export const catalog: Record<
|
|
8
|
+
export const catalog: Record<BuiltInProviderId, ProviderCatalogEntry> =
|
|
9
9
|
mergeManualCatalog(generatedCatalog);
|