@ottocode/sdk 0.1.265 → 0.1.267

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 (31) hide show
  1. package/package.json +2 -2
  2. package/src/config/src/index.ts +4 -0
  3. package/src/config/src/manager.ts +8 -14
  4. package/src/config/src/paths.ts +4 -0
  5. package/src/core/src/providers/resolver.ts +29 -70
  6. package/src/core/src/tools/bin-manager/cache.ts +13 -0
  7. package/src/core/src/tools/bin-manager/filesystem.ts +32 -0
  8. package/src/core/src/tools/bin-manager/paths.ts +36 -0
  9. package/src/core/src/tools/bin-manager/vendor.ts +80 -0
  10. package/src/core/src/tools/bin-manager.ts +14 -140
  11. package/src/core/src/tools/builtin/patch/apply-hunk.ts +308 -0
  12. package/src/core/src/tools/builtin/patch/apply-report.ts +99 -0
  13. package/src/core/src/tools/builtin/patch/apply.ts +6 -663
  14. package/src/core/src/tools/builtin/patch/hunk-header.ts +17 -0
  15. package/src/core/src/tools/builtin/patch/indentation.ts +160 -0
  16. package/src/core/src/tools/builtin/patch/matching.ts +58 -0
  17. package/src/core/src/tools/builtin/patch/parse-enveloped.ts +10 -72
  18. package/src/core/src/tools/builtin/patch/parse-unified.ts +15 -105
  19. package/src/core/src/tools/builtin/patch/replace-builder.ts +64 -0
  20. package/src/core/src/tools/builtin/patch/unified-state.ts +86 -0
  21. package/src/core/src/tools/builtin/websearch-strategies.ts +197 -0
  22. package/src/core/src/tools/builtin/websearch.ts +9 -187
  23. package/src/core/src/tools/loader.ts +6 -49
  24. package/src/core/src/tools/plugin-discovery.ts +86 -0
  25. package/src/core/src/utils/logger/format.ts +50 -0
  26. package/src/core/src/utils/logger/sinks.ts +61 -0
  27. package/src/core/src/utils/logger.ts +2 -119
  28. package/src/index.ts +3 -0
  29. package/src/providers/src/index.ts +4 -0
  30. package/src/providers/src/model-resolution.ts +21 -0
  31. package/src/providers/src/zai-client.ts +5 -2
@@ -1,51 +1,6 @@
1
- import { appendFileSync, mkdirSync } from 'node:fs';
2
- import { dirname } from 'node:path';
3
1
  import { isDebugEnabled, isTraceEnabled, getDebugScopes } from './debug.ts';
4
- import {
5
- getGlobalDebugLogPath,
6
- getSessionDebugDetailsLogPath,
7
- getSessionDebugLogPath,
8
- } from '../../../config/src/paths.ts';
9
-
10
- export type LogLevel = 'debug' | 'info' | 'warn' | 'error';
11
-
12
- const ANSI_RESET = '\x1b[0m';
13
- const ANSI_DIM = '\x1b[2m';
14
- const ANSI_CYAN = '\x1b[36m';
15
- const ANSI_BLUE = '\x1b[34m';
16
- const ANSI_GREEN = '\x1b[32m';
17
- const ANSI_YELLOW = '\x1b[33m';
18
- const ANSI_RED = '\x1b[31m';
19
-
20
- function safeHasMeta(
21
- meta?: Record<string, unknown>,
22
- ): meta is Record<string, unknown> {
23
- return Boolean(meta && Object.keys(meta).length);
24
- }
25
-
26
- function getDebugLogFilePath(): string | undefined {
27
- if (!isDebugEnabled()) return undefined;
28
- return getGlobalDebugLogPath();
29
- }
30
-
31
- function getSessionLogFilePath(
32
- meta?: Record<string, unknown>,
33
- ): string | undefined {
34
- if (!isDebugEnabled()) return undefined;
35
- if (meta?.debugDetail === true) return undefined;
36
- const sessionId = meta?.sessionId;
37
- if (typeof sessionId !== 'string' || !sessionId.trim()) return undefined;
38
- return getSessionDebugLogPath(sessionId);
39
- }
40
-
41
- function getSessionDetailsLogFilePath(
42
- meta?: Record<string, unknown>,
43
- ): string | undefined {
44
- if (!isDebugEnabled()) return undefined;
45
- const sessionId = meta?.sessionId;
46
- if (typeof sessionId !== 'string' || !sessionId.trim()) return undefined;
47
- return getSessionDebugDetailsLogPath(sessionId);
48
- }
2
+ import { colorizeLine, safeHasMeta, type LogLevel } from './logger/format.ts';
3
+ import { writeLogLine } from './logger/sinks.ts';
49
4
 
50
5
  function shouldWriteDebugLog(message: string): boolean {
51
6
  if (!isDebugEnabled()) return false;
@@ -56,41 +11,6 @@ function shouldWriteDebugLog(message: string): boolean {
56
11
  return scopes.includes(match[1]);
57
12
  }
58
13
 
59
- function serializeLogMeta(meta?: Record<string, unknown>): string {
60
- if (!safeHasMeta(meta)) return '';
61
- try {
62
- const sanitized = { ...meta };
63
- delete sanitized.debugDetail;
64
- return Object.keys(sanitized).length ? ` ${JSON.stringify(sanitized)}` : '';
65
- } catch {
66
- return ' [unserializable-meta]';
67
- }
68
- }
69
-
70
- function colorizeLine(line: string, level: LogLevel): string {
71
- const levelColor =
72
- level === 'debug'
73
- ? ANSI_CYAN
74
- : level === 'info'
75
- ? ANSI_BLUE
76
- : level === 'warn'
77
- ? ANSI_YELLOW
78
- : ANSI_RED;
79
- const scopeMatch = line.match(
80
- /\[(debug|info|warn|error|timing)\]\s+\[([^\]]+)\]/i,
81
- );
82
- if (!scopeMatch) {
83
- return `${levelColor}${line}${ANSI_RESET}`;
84
- }
85
- const rest = line.slice(24);
86
- return `${ANSI_DIM}${line.slice(0, 24)}${ANSI_RESET}${rest
87
- .replace(scopeMatch[1], `${levelColor}${scopeMatch[1]}${ANSI_RESET}`)
88
- .replace(
89
- `[${scopeMatch[2]}]`,
90
- `${ANSI_GREEN}[${scopeMatch[2]}]${ANSI_RESET}`,
91
- )}`;
92
- }
93
-
94
14
  function printLine(
95
15
  level: LogLevel,
96
16
  line: string,
@@ -108,43 +28,6 @@ function printLine(
108
28
  else console.log(colored);
109
29
  }
110
30
 
111
- function writeLogLine(line: string, meta?: Record<string, unknown>) {
112
- const suffix = serializeLogMeta(meta);
113
- const fullLine = `${new Date().toISOString()} ${line}${suffix}`;
114
- const logFile = getDebugLogFilePath();
115
-
116
- if (logFile) {
117
- try {
118
- mkdirSync(dirname(logFile), { recursive: true });
119
- appendFileSync(logFile, `${fullLine}\n`, 'utf-8');
120
- } catch {
121
- // ignore file logging errors
122
- }
123
- }
124
-
125
- const sessionLogFile = getSessionLogFilePath(meta);
126
- if (sessionLogFile) {
127
- try {
128
- mkdirSync(dirname(sessionLogFile), { recursive: true });
129
- appendFileSync(sessionLogFile, `${fullLine}\n`, 'utf-8');
130
- } catch {
131
- // ignore file logging errors
132
- }
133
- }
134
-
135
- const sessionDetailsLogFile = getSessionDetailsLogFilePath(meta);
136
- if (sessionDetailsLogFile) {
137
- try {
138
- mkdirSync(dirname(sessionDetailsLogFile), { recursive: true });
139
- appendFileSync(sessionDetailsLogFile, `${fullLine}\n`, 'utf-8');
140
- } catch {
141
- // ignore file logging errors
142
- }
143
- }
144
-
145
- return fullLine;
146
- }
147
-
148
31
  export function debug(message: string, meta?: Record<string, unknown>): void {
149
32
  if (!shouldWriteDebugLog(message)) return;
150
33
  try {
package/src/index.ts CHANGED
@@ -72,6 +72,8 @@ export type { UnderlyingProviderKey } from './providers/src/index.ts';
72
72
  export {
73
73
  discoverOllamaModels,
74
74
  normalizeOllamaBaseURL,
75
+ resolveOpenAIResponsesModel,
76
+ shouldUseOpenAIResponsesApi,
75
77
  } from './providers/src/index.ts';
76
78
  export type {
77
79
  DiscoverOllamaOptions,
@@ -216,6 +218,7 @@ export {
216
218
  getLocalDataDir,
217
219
  getGlobalConfigDir,
218
220
  getGlobalConfigPath,
221
+ getGlobalSkillsConfigPath,
219
222
  getGlobalAgentsJsonPath,
220
223
  getGlobalAgentsDir,
221
224
  getGlobalToolsDir,
@@ -42,6 +42,10 @@ export {
42
42
  discoverOllamaModels,
43
43
  normalizeOllamaBaseURL,
44
44
  } from './ollama-discovery.ts';
45
+ export {
46
+ resolveOpenAIResponsesModel,
47
+ shouldUseOpenAIResponsesApi,
48
+ } from './model-resolution.ts';
45
49
  export type {
46
50
  DiscoverOllamaOptions,
47
51
  DiscoverOllamaResult,
@@ -0,0 +1,21 @@
1
+ import type { createOpenAI } from '@ai-sdk/openai';
2
+
3
+ export function shouldUseOpenAIResponsesApi(model: string): boolean {
4
+ const lower = model.toLowerCase();
5
+ return (
6
+ lower.includes('gpt-5') ||
7
+ lower.startsWith('o1') ||
8
+ lower.startsWith('o3') ||
9
+ lower.startsWith('o4') ||
10
+ lower.includes('codex-mini')
11
+ );
12
+ }
13
+
14
+ export function resolveOpenAIResponsesModel(
15
+ instance: ReturnType<typeof createOpenAI>,
16
+ model: string,
17
+ ) {
18
+ return shouldUseOpenAIResponsesApi(model)
19
+ ? instance.responses(model)
20
+ : instance(model);
21
+ }
@@ -3,11 +3,13 @@ import { catalog } from './catalog-merged.ts';
3
3
 
4
4
  export type ZaiProviderConfig = {
5
5
  apiKey?: string;
6
+ baseURL?: string;
6
7
  };
7
8
 
8
9
  export function createZaiModel(model: string, config?: ZaiProviderConfig) {
9
10
  const entry = catalog.zai;
10
- const baseURL = entry?.api || 'https://api.z.ai/api/paas/v4';
11
+ const baseURL =
12
+ config?.baseURL || entry?.api || 'https://api.z.ai/api/paas/v4';
11
13
  const apiKey =
12
14
  config?.apiKey ||
13
15
  process.env.ZAI_API_KEY ||
@@ -29,7 +31,8 @@ export function createZaiCodingModel(
29
31
  config?: ZaiProviderConfig,
30
32
  ) {
31
33
  const entry = catalog['zai-coding'];
32
- const baseURL = entry?.api || 'https://api.z.ai/api/coding/paas/v4';
34
+ const baseURL =
35
+ config?.baseURL || entry?.api || 'https://api.z.ai/api/coding/paas/v4';
33
36
  const apiKey =
34
37
  config?.apiKey ||
35
38
  process.env.ZAI_CODING_API_KEY ||