@ottocode/sdk 0.1.265 → 0.1.266
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 +2 -2
- package/src/core/src/providers/resolver.ts +29 -70
- package/src/core/src/tools/bin-manager/cache.ts +13 -0
- package/src/core/src/tools/bin-manager/filesystem.ts +32 -0
- package/src/core/src/tools/bin-manager/paths.ts +36 -0
- package/src/core/src/tools/bin-manager/vendor.ts +80 -0
- package/src/core/src/tools/bin-manager.ts +14 -140
- package/src/core/src/tools/builtin/patch/apply-hunk.ts +308 -0
- package/src/core/src/tools/builtin/patch/apply-report.ts +99 -0
- package/src/core/src/tools/builtin/patch/apply.ts +6 -663
- package/src/core/src/tools/builtin/patch/hunk-header.ts +17 -0
- package/src/core/src/tools/builtin/patch/indentation.ts +160 -0
- package/src/core/src/tools/builtin/patch/matching.ts +58 -0
- package/src/core/src/tools/builtin/patch/parse-enveloped.ts +10 -72
- package/src/core/src/tools/builtin/patch/parse-unified.ts +15 -105
- package/src/core/src/tools/builtin/patch/replace-builder.ts +64 -0
- package/src/core/src/tools/builtin/patch/unified-state.ts +86 -0
- package/src/core/src/tools/builtin/websearch-strategies.ts +197 -0
- package/src/core/src/tools/builtin/websearch.ts +9 -187
- package/src/core/src/tools/loader.ts +6 -49
- package/src/core/src/tools/plugin-discovery.ts +86 -0
- package/src/core/src/utils/logger/format.ts +50 -0
- package/src/core/src/utils/logger/sinks.ts +61 -0
- package/src/core/src/utils/logger.ts +2 -119
- package/src/index.ts +2 -0
- package/src/providers/src/index.ts +4 -0
- package/src/providers/src/model-resolution.ts +21 -0
- 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
|
-
|
|
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,
|
|
@@ -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 =
|
|
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 =
|
|
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 ||
|