@codeany/open-agent-sdk 0.1.0 → 0.2.1
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/README.md +144 -31
- package/dist/agent.d.ts +113 -0
- package/dist/agent.d.ts.map +1 -0
- package/dist/agent.js +446 -0
- package/dist/agent.js.map +1 -0
- package/dist/engine.d.ts +62 -0
- package/dist/engine.d.ts.map +1 -0
- package/dist/engine.js +494 -0
- package/dist/engine.js.map +1 -0
- package/dist/hooks.d.ts +111 -0
- package/dist/hooks.d.ts.map +1 -0
- package/dist/hooks.js +179 -0
- package/dist/hooks.js.map +1 -0
- package/dist/index.d.ts +66 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +133 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp/client.d.ts +19 -0
- package/dist/mcp/client.d.ts.map +1 -0
- package/dist/mcp/client.js +126 -0
- package/dist/mcp/client.js.map +1 -0
- package/dist/providers/anthropic.d.ts +17 -0
- package/dist/providers/anthropic.d.ts.map +1 -0
- package/dist/providers/anthropic.js +47 -0
- package/dist/providers/anthropic.js.map +1 -0
- package/dist/providers/index.d.ts +20 -0
- package/dist/providers/index.d.ts.map +1 -0
- package/dist/providers/index.js +26 -0
- package/dist/providers/index.js.map +1 -0
- package/dist/providers/openai.d.ts +26 -0
- package/dist/providers/openai.d.ts.map +1 -0
- package/dist/providers/openai.js +212 -0
- package/dist/providers/openai.js.map +1 -0
- package/dist/providers/types.d.ts +84 -0
- package/dist/providers/types.d.ts.map +1 -0
- package/dist/providers/types.js +11 -0
- package/dist/providers/types.js.map +1 -0
- package/dist/sdk-mcp-server.d.ts +52 -0
- package/dist/sdk-mcp-server.d.ts.map +1 -0
- package/dist/sdk-mcp-server.js +57 -0
- package/dist/sdk-mcp-server.js.map +1 -0
- package/dist/session.d.ts +73 -0
- package/dist/session.d.ts.map +1 -0
- package/dist/session.js +159 -0
- package/dist/session.js.map +1 -0
- package/dist/skills/bundled/commit.d.ts +7 -0
- package/dist/skills/bundled/commit.d.ts.map +1 -0
- package/dist/skills/bundled/commit.js +35 -0
- package/dist/skills/bundled/commit.js.map +1 -0
- package/dist/skills/bundled/debug.d.ts +7 -0
- package/dist/skills/bundled/debug.d.ts.map +1 -0
- package/dist/skills/bundled/debug.js +46 -0
- package/dist/skills/bundled/debug.js.map +1 -0
- package/dist/skills/bundled/index.d.ts +11 -0
- package/dist/skills/bundled/index.d.ts.map +1 -0
- package/dist/skills/bundled/index.js +26 -0
- package/dist/skills/bundled/index.js.map +1 -0
- package/dist/skills/bundled/review.d.ts +7 -0
- package/dist/skills/bundled/review.d.ts.map +1 -0
- package/dist/skills/bundled/review.js +38 -0
- package/dist/skills/bundled/review.js.map +1 -0
- package/dist/skills/bundled/simplify.d.ts +8 -0
- package/dist/skills/bundled/simplify.d.ts.map +1 -0
- package/dist/skills/bundled/simplify.js +48 -0
- package/dist/skills/bundled/simplify.js.map +1 -0
- package/dist/skills/bundled/test.d.ts +7 -0
- package/dist/skills/bundled/test.d.ts.map +1 -0
- package/dist/skills/bundled/test.js +40 -0
- package/dist/skills/bundled/test.js.map +1 -0
- package/dist/skills/index.d.ts +7 -0
- package/dist/skills/index.d.ts.map +1 -0
- package/dist/skills/index.js +8 -0
- package/dist/skills/index.js.map +1 -0
- package/dist/skills/registry.d.ts +43 -0
- package/dist/skills/registry.d.ts.map +1 -0
- package/dist/skills/registry.js +111 -0
- package/dist/skills/registry.js.map +1 -0
- package/dist/skills/types.d.ts +83 -0
- package/dist/skills/types.d.ts.map +1 -0
- package/dist/skills/types.js +8 -0
- package/dist/skills/types.js.map +1 -0
- package/dist/tool-helper.d.ts +73 -0
- package/dist/tool-helper.d.ts.map +1 -0
- package/dist/tool-helper.js +86 -0
- package/dist/tool-helper.js.map +1 -0
- package/dist/tools/agent-tool.d.ts +17 -0
- package/dist/tools/agent-tool.d.ts.map +1 -0
- package/dist/tools/agent-tool.js +146 -0
- package/dist/tools/agent-tool.js.map +1 -0
- package/dist/tools/ask-user.d.ts +18 -0
- package/dist/tools/ask-user.d.ts.map +1 -0
- package/dist/tools/ask-user.js +72 -0
- package/dist/tools/ask-user.js.map +1 -0
- package/dist/tools/bash.d.ts +5 -0
- package/dist/tools/bash.d.ts.map +1 -0
- package/dist/tools/bash.js +67 -0
- package/dist/tools/bash.js.map +1 -0
- package/dist/tools/config-tool.d.ts +20 -0
- package/dist/tools/config-tool.d.ts.map +1 -0
- package/dist/tools/config-tool.js +83 -0
- package/dist/tools/config-tool.js.map +1 -0
- package/dist/tools/cron-tools.d.ts +33 -0
- package/dist/tools/cron-tools.d.ts.map +1 -0
- package/dist/tools/cron-tools.js +128 -0
- package/dist/tools/cron-tools.js.map +1 -0
- package/dist/tools/edit.d.ts +5 -0
- package/dist/tools/edit.d.ts.map +1 -0
- package/dist/tools/edit.js +70 -0
- package/dist/tools/edit.js.map +1 -0
- package/dist/tools/glob.d.ts +5 -0
- package/dist/tools/glob.d.ts.map +1 -0
- package/dist/tools/glob.js +75 -0
- package/dist/tools/glob.js.map +1 -0
- package/dist/tools/grep.d.ts +5 -0
- package/dist/tools/grep.d.ts.map +1 -0
- package/dist/tools/grep.js +168 -0
- package/dist/tools/grep.js.map +1 -0
- package/dist/tools/index.d.ts +45 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +162 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/lsp-tool.d.ts +9 -0
- package/dist/tools/lsp-tool.d.ts.map +1 -0
- package/dist/tools/lsp-tool.js +137 -0
- package/dist/tools/lsp-tool.js.map +1 -0
- package/dist/tools/mcp-resource-tools.d.ts +14 -0
- package/dist/tools/mcp-resource-tools.d.ts.map +1 -0
- package/dist/tools/mcp-resource-tools.js +117 -0
- package/dist/tools/mcp-resource-tools.js.map +1 -0
- package/dist/tools/notebook-edit.d.ts +5 -0
- package/dist/tools/notebook-edit.d.ts.map +1 -0
- package/dist/tools/notebook-edit.js +85 -0
- package/dist/tools/notebook-edit.js.map +1 -0
- package/dist/tools/plan-tools.d.ts +12 -0
- package/dist/tools/plan-tools.d.ts.map +1 -0
- package/dist/tools/plan-tools.js +77 -0
- package/dist/tools/plan-tools.js.map +1 -0
- package/dist/tools/read.d.ts +5 -0
- package/dist/tools/read.d.ts.map +1 -0
- package/dist/tools/read.js +66 -0
- package/dist/tools/read.js.map +1 -0
- package/dist/tools/send-message.d.ts +31 -0
- package/dist/tools/send-message.d.ts.map +1 -0
- package/dist/tools/send-message.js +77 -0
- package/dist/tools/send-message.js.map +1 -0
- package/dist/tools/skill-tool.d.ts +9 -0
- package/dist/tools/skill-tool.d.ts.map +1 -0
- package/dist/tools/skill-tool.js +115 -0
- package/dist/tools/skill-tool.js.map +1 -0
- package/dist/tools/task-tools.d.ts +48 -0
- package/dist/tools/task-tools.d.ts.map +1 -0
- package/dist/tools/task-tools.js +242 -0
- package/dist/tools/task-tools.js.map +1 -0
- package/dist/tools/team-tools.d.ts +34 -0
- package/dist/tools/team-tools.d.ts.map +1 -0
- package/dist/tools/team-tools.js +103 -0
- package/dist/tools/team-tools.js.map +1 -0
- package/dist/tools/todo-tool.d.ts +22 -0
- package/dist/tools/todo-tool.d.ts.map +1 -0
- package/dist/tools/todo-tool.js +93 -0
- package/dist/tools/todo-tool.js.map +1 -0
- package/dist/tools/tool-search.d.ts +13 -0
- package/dist/tools/tool-search.d.ts.map +1 -0
- package/dist/tools/tool-search.js +76 -0
- package/dist/tools/tool-search.js.map +1 -0
- package/dist/tools/types.d.ts +29 -0
- package/dist/tools/types.d.ts.map +1 -0
- package/dist/tools/types.js +52 -0
- package/dist/tools/types.js.map +1 -0
- package/dist/tools/web-fetch.d.ts +5 -0
- package/dist/tools/web-fetch.d.ts.map +1 -0
- package/dist/tools/web-fetch.js +60 -0
- package/dist/tools/web-fetch.js.map +1 -0
- package/dist/tools/web-search.d.ts +5 -0
- package/dist/tools/web-search.d.ts.map +1 -0
- package/dist/tools/web-search.js +77 -0
- package/dist/tools/web-search.js.map +1 -0
- package/dist/tools/worktree-tools.d.ts +10 -0
- package/dist/tools/worktree-tools.d.ts.map +1 -0
- package/dist/tools/worktree-tools.js +130 -0
- package/dist/tools/worktree-tools.js.map +1 -0
- package/dist/tools/write.d.ts +5 -0
- package/dist/tools/write.d.ts.map +1 -0
- package/dist/tools/write.js +40 -0
- package/dist/tools/write.js.map +1 -0
- package/dist/types.d.ts +423 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +5 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/compact.d.ts +44 -0
- package/dist/utils/compact.d.ts.map +1 -0
- package/dist/utils/compact.js +162 -0
- package/dist/utils/compact.js.map +1 -0
- package/dist/utils/context.d.ts +35 -0
- package/dist/utils/context.d.ts.map +1 -0
- package/dist/utils/context.js +174 -0
- package/dist/utils/context.js.map +1 -0
- package/dist/utils/fileCache.d.ts +64 -0
- package/dist/utils/fileCache.d.ts.map +1 -0
- package/dist/utils/fileCache.js +117 -0
- package/dist/utils/fileCache.js.map +1 -0
- package/dist/utils/messages.d.ts +57 -0
- package/dist/utils/messages.d.ts.map +1 -0
- package/dist/utils/messages.js +152 -0
- package/dist/utils/messages.js.map +1 -0
- package/dist/utils/retry.d.ts +48 -0
- package/dist/utils/retry.d.ts.map +1 -0
- package/dist/utils/retry.js +111 -0
- package/dist/utils/retry.js.map +1 -0
- package/dist/utils/tokens.d.ts +57 -0
- package/dist/utils/tokens.d.ts.map +1 -0
- package/dist/utils/tokens.js +134 -0
- package/dist/utils/tokens.js.map +1 -0
- package/package.json +7 -1
- package/src/agent.ts +106 -15
- package/src/engine.ts +169 -59
- package/src/index.ts +51 -1
- package/src/providers/anthropic.ts +60 -0
- package/src/providers/index.ts +34 -0
- package/src/providers/openai.ts +315 -0
- package/src/providers/types.ts +85 -0
- package/src/session.ts +5 -5
- package/src/skills/bundled/commit.ts +38 -0
- package/src/skills/bundled/debug.ts +48 -0
- package/src/skills/bundled/index.ts +28 -0
- package/src/skills/bundled/review.ts +41 -0
- package/src/skills/bundled/simplify.ts +51 -0
- package/src/skills/bundled/test.ts +43 -0
- package/src/skills/index.ts +25 -0
- package/src/skills/registry.ts +133 -0
- package/src/skills/types.ts +99 -0
- package/src/tools/agent-tool.ts +13 -2
- package/src/tools/index.ts +8 -0
- package/src/tools/skill-tool.ts +133 -0
- package/src/tools/types.ts +7 -3
- package/src/types.ts +35 -8
- package/src/utils/compact.ts +18 -17
- package/src/utils/messages.ts +12 -13
- package/src/utils/tokens.ts +29 -6
- package/.env.example +0 -8
- package/examples/01-simple-query.ts +0 -43
- package/examples/02-multi-tool.ts +0 -44
- package/examples/03-multi-turn.ts +0 -39
- package/examples/04-prompt-api.ts +0 -29
- package/examples/05-custom-system-prompt.ts +0 -26
- package/examples/06-mcp-server.ts +0 -49
- package/examples/07-custom-tools.ts +0 -87
- package/examples/08-official-api-compat.ts +0 -38
- package/examples/09-subagents.ts +0 -48
- package/examples/10-permissions.ts +0 -40
- package/examples/11-custom-mcp-tools.ts +0 -101
- package/examples/web/index.html +0 -365
- package/examples/web/server.ts +0 -157
- package/tsconfig.json +0 -19
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Retry Logic with Exponential Backoff
|
|
3
|
+
*
|
|
4
|
+
* Handles API retries for rate limits, overloaded servers,
|
|
5
|
+
* and transient failures.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Retry configuration.
|
|
9
|
+
*/
|
|
10
|
+
export interface RetryConfig {
|
|
11
|
+
maxRetries: number;
|
|
12
|
+
baseDelayMs: number;
|
|
13
|
+
maxDelayMs: number;
|
|
14
|
+
retryableStatusCodes: number[];
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Default retry configuration.
|
|
18
|
+
*/
|
|
19
|
+
export declare const DEFAULT_RETRY_CONFIG: RetryConfig;
|
|
20
|
+
/**
|
|
21
|
+
* Check if an error is retryable.
|
|
22
|
+
*/
|
|
23
|
+
export declare function isRetryableError(err: any, config?: RetryConfig): boolean;
|
|
24
|
+
/**
|
|
25
|
+
* Calculate delay for exponential backoff.
|
|
26
|
+
*/
|
|
27
|
+
export declare function getRetryDelay(attempt: number, config?: RetryConfig): number;
|
|
28
|
+
/**
|
|
29
|
+
* Execute a function with retries.
|
|
30
|
+
*/
|
|
31
|
+
export declare function withRetry<T>(fn: () => Promise<T>, config?: RetryConfig, abortSignal?: AbortSignal): Promise<T>;
|
|
32
|
+
/**
|
|
33
|
+
* Check if an error is a "prompt too long" error.
|
|
34
|
+
*/
|
|
35
|
+
export declare function isPromptTooLongError(err: any): boolean;
|
|
36
|
+
/**
|
|
37
|
+
* Check if error is an auth error.
|
|
38
|
+
*/
|
|
39
|
+
export declare function isAuthError(err: any): boolean;
|
|
40
|
+
/**
|
|
41
|
+
* Check if error is a rate limit error.
|
|
42
|
+
*/
|
|
43
|
+
export declare function isRateLimitError(err: any): boolean;
|
|
44
|
+
/**
|
|
45
|
+
* Format an API error for display.
|
|
46
|
+
*/
|
|
47
|
+
export declare function formatApiError(err: any): string;
|
|
48
|
+
//# sourceMappingURL=retry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retry.d.ts","sourceRoot":"","sources":["../../src/utils/retry.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,UAAU,EAAE,MAAM,CAAA;IAClB,WAAW,EAAE,MAAM,CAAA;IACnB,UAAU,EAAE,MAAM,CAAA;IAClB,oBAAoB,EAAE,MAAM,EAAE,CAAA;CAC/B;AAED;;GAEG;AACH,eAAO,MAAM,oBAAoB,EAAE,WAKlC,CAAA;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,GAAG,EAAE,MAAM,GAAE,WAAkC,GAAG,OAAO,CAgB9F;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,GAAE,WAAkC,GAAG,MAAM,CAKjG;AAED;;GAEG;AACH,wBAAsB,SAAS,CAAC,CAAC,EAC/B,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACpB,MAAM,GAAE,WAAkC,EAC1C,WAAW,CAAC,EAAE,WAAW,GACxB,OAAO,CAAC,CAAC,CAAC,CA4BZ;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,GAAG,GAAG,OAAO,CAQtD;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,GAAG,GAAG,OAAO,CAE7C;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,GAAG,GAAG,OAAO,CAElD;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,GAAG,GAAG,MAAM,CAc/C"}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Retry Logic with Exponential Backoff
|
|
3
|
+
*
|
|
4
|
+
* Handles API retries for rate limits, overloaded servers,
|
|
5
|
+
* and transient failures.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Default retry configuration.
|
|
9
|
+
*/
|
|
10
|
+
export const DEFAULT_RETRY_CONFIG = {
|
|
11
|
+
maxRetries: 3,
|
|
12
|
+
baseDelayMs: 2000,
|
|
13
|
+
maxDelayMs: 30000,
|
|
14
|
+
retryableStatusCodes: [429, 500, 502, 503, 529],
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Check if an error is retryable.
|
|
18
|
+
*/
|
|
19
|
+
export function isRetryableError(err, config = DEFAULT_RETRY_CONFIG) {
|
|
20
|
+
if (err?.status && config.retryableStatusCodes.includes(err.status)) {
|
|
21
|
+
return true;
|
|
22
|
+
}
|
|
23
|
+
// Network errors
|
|
24
|
+
if (err?.code === 'ECONNRESET' || err?.code === 'ETIMEDOUT' || err?.code === 'ECONNREFUSED') {
|
|
25
|
+
return true;
|
|
26
|
+
}
|
|
27
|
+
// API overloaded
|
|
28
|
+
if (err?.error?.type === 'overloaded_error') {
|
|
29
|
+
return true;
|
|
30
|
+
}
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Calculate delay for exponential backoff.
|
|
35
|
+
*/
|
|
36
|
+
export function getRetryDelay(attempt, config = DEFAULT_RETRY_CONFIG) {
|
|
37
|
+
const delay = config.baseDelayMs * Math.pow(2, attempt);
|
|
38
|
+
// Add jitter (±25%)
|
|
39
|
+
const jitter = delay * 0.25 * (Math.random() * 2 - 1);
|
|
40
|
+
return Math.min(delay + jitter, config.maxDelayMs);
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Execute a function with retries.
|
|
44
|
+
*/
|
|
45
|
+
export async function withRetry(fn, config = DEFAULT_RETRY_CONFIG, abortSignal) {
|
|
46
|
+
let lastError;
|
|
47
|
+
for (let attempt = 0; attempt <= config.maxRetries; attempt++) {
|
|
48
|
+
if (abortSignal?.aborted) {
|
|
49
|
+
throw new Error('Aborted');
|
|
50
|
+
}
|
|
51
|
+
try {
|
|
52
|
+
return await fn();
|
|
53
|
+
}
|
|
54
|
+
catch (err) {
|
|
55
|
+
lastError = err;
|
|
56
|
+
if (!isRetryableError(err, config)) {
|
|
57
|
+
throw err;
|
|
58
|
+
}
|
|
59
|
+
if (attempt === config.maxRetries) {
|
|
60
|
+
throw err;
|
|
61
|
+
}
|
|
62
|
+
// Wait before retry
|
|
63
|
+
const delay = getRetryDelay(attempt, config);
|
|
64
|
+
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
throw lastError;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Check if an error is a "prompt too long" error.
|
|
71
|
+
*/
|
|
72
|
+
export function isPromptTooLongError(err) {
|
|
73
|
+
if (err?.status === 400) {
|
|
74
|
+
const message = err?.error?.error?.message || err?.message || '';
|
|
75
|
+
return message.includes('prompt is too long') ||
|
|
76
|
+
message.includes('max_tokens') ||
|
|
77
|
+
message.includes('context length');
|
|
78
|
+
}
|
|
79
|
+
return false;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Check if error is an auth error.
|
|
83
|
+
*/
|
|
84
|
+
export function isAuthError(err) {
|
|
85
|
+
return err?.status === 401 || err?.status === 403;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Check if error is a rate limit error.
|
|
89
|
+
*/
|
|
90
|
+
export function isRateLimitError(err) {
|
|
91
|
+
return err?.status === 429;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Format an API error for display.
|
|
95
|
+
*/
|
|
96
|
+
export function formatApiError(err) {
|
|
97
|
+
if (isAuthError(err)) {
|
|
98
|
+
return 'Authentication failed. Check your CODEANY_API_KEY.';
|
|
99
|
+
}
|
|
100
|
+
if (isRateLimitError(err)) {
|
|
101
|
+
return 'Rate limit exceeded. Please retry after a short wait.';
|
|
102
|
+
}
|
|
103
|
+
if (err?.status === 529) {
|
|
104
|
+
return 'API overloaded. Please retry later.';
|
|
105
|
+
}
|
|
106
|
+
if (isPromptTooLongError(err)) {
|
|
107
|
+
return 'Prompt too long. Auto-compacting conversation...';
|
|
108
|
+
}
|
|
109
|
+
return `API error: ${err.message || err}`;
|
|
110
|
+
}
|
|
111
|
+
//# sourceMappingURL=retry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retry.js","sourceRoot":"","sources":["../../src/utils/retry.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Token Estimation & Counting
|
|
3
|
+
*
|
|
4
|
+
* Provides rough token estimation (character-based) and
|
|
5
|
+
* API-based exact counting when available.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Rough token estimation: ~4 chars per token (conservative).
|
|
9
|
+
*/
|
|
10
|
+
export declare function estimateTokens(text: string): number;
|
|
11
|
+
/**
|
|
12
|
+
* Estimate tokens for a message array.
|
|
13
|
+
*/
|
|
14
|
+
export declare function estimateMessagesTokens(messages: Array<{
|
|
15
|
+
role: string;
|
|
16
|
+
content: any;
|
|
17
|
+
}>): number;
|
|
18
|
+
/**
|
|
19
|
+
* Estimate tokens for a system prompt.
|
|
20
|
+
*/
|
|
21
|
+
export declare function estimateSystemPromptTokens(systemPrompt: string): number;
|
|
22
|
+
/**
|
|
23
|
+
* Count tokens from API usage response.
|
|
24
|
+
*/
|
|
25
|
+
export declare function getTokenCountFromUsage(usage: {
|
|
26
|
+
input_tokens: number;
|
|
27
|
+
output_tokens: number;
|
|
28
|
+
cache_creation_input_tokens?: number;
|
|
29
|
+
cache_read_input_tokens?: number;
|
|
30
|
+
}): number;
|
|
31
|
+
/**
|
|
32
|
+
* Get the context window size for a model.
|
|
33
|
+
*/
|
|
34
|
+
export declare function getContextWindowSize(model: string): number;
|
|
35
|
+
/**
|
|
36
|
+
* Auto-compact buffer: trigger compaction when within this many tokens of the limit.
|
|
37
|
+
*/
|
|
38
|
+
export declare const AUTOCOMPACT_BUFFER_TOKENS = 13000;
|
|
39
|
+
/**
|
|
40
|
+
* Get the auto-compact threshold for a model.
|
|
41
|
+
*/
|
|
42
|
+
export declare function getAutoCompactThreshold(model: string): number;
|
|
43
|
+
/**
|
|
44
|
+
* Model pricing (USD per token).
|
|
45
|
+
*/
|
|
46
|
+
export declare const MODEL_PRICING: Record<string, {
|
|
47
|
+
input: number;
|
|
48
|
+
output: number;
|
|
49
|
+
}>;
|
|
50
|
+
/**
|
|
51
|
+
* Estimate cost from usage and model.
|
|
52
|
+
*/
|
|
53
|
+
export declare function estimateCost(model: string, usage: {
|
|
54
|
+
input_tokens: number;
|
|
55
|
+
output_tokens: number;
|
|
56
|
+
}): number;
|
|
57
|
+
//# sourceMappingURL=tokens.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tokens.d.ts","sourceRoot":"","sources":["../../src/utils/tokens.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;GAEG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,GAAG,CAAA;CAAE,CAAC,GAC9C,MAAM,CAmBR;AAED;;GAEG;AACH,wBAAgB,0BAA0B,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAEvE;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE;IAC5C,YAAY,EAAE,MAAM,CAAA;IACpB,aAAa,EAAE,MAAM,CAAA;IACrB,2BAA2B,CAAC,EAAE,MAAM,CAAA;IACpC,uBAAuB,CAAC,EAAE,MAAM,CAAA;CACjC,GAAG,MAAM,CAOT;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAuB1D;AAED;;GAEG;AACH,eAAO,MAAM,yBAAyB,QAAS,CAAA;AAE/C;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE7D;AAED;;GAEG;AACH,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAuB3E,CAAA;AAED;;GAEG;AACH,wBAAgB,YAAY,CAC1B,KAAK,EAAE,MAAM,EACb,KAAK,EAAE;IAAE,YAAY,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAE,GACrD,MAAM,CAMR"}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Token Estimation & Counting
|
|
3
|
+
*
|
|
4
|
+
* Provides rough token estimation (character-based) and
|
|
5
|
+
* API-based exact counting when available.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Rough token estimation: ~4 chars per token (conservative).
|
|
9
|
+
*/
|
|
10
|
+
export function estimateTokens(text) {
|
|
11
|
+
return Math.ceil(text.length / 4);
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Estimate tokens for a message array.
|
|
15
|
+
*/
|
|
16
|
+
export function estimateMessagesTokens(messages) {
|
|
17
|
+
let total = 0;
|
|
18
|
+
for (const msg of messages) {
|
|
19
|
+
if (typeof msg.content === 'string') {
|
|
20
|
+
total += estimateTokens(msg.content);
|
|
21
|
+
}
|
|
22
|
+
else if (Array.isArray(msg.content)) {
|
|
23
|
+
for (const block of msg.content) {
|
|
24
|
+
if ('text' in block && typeof block.text === 'string') {
|
|
25
|
+
total += estimateTokens(block.text);
|
|
26
|
+
}
|
|
27
|
+
else if ('content' in block && typeof block.content === 'string') {
|
|
28
|
+
total += estimateTokens(block.content);
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
// tool_use, image, etc - rough estimate
|
|
32
|
+
total += estimateTokens(JSON.stringify(block));
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return total;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Estimate tokens for a system prompt.
|
|
41
|
+
*/
|
|
42
|
+
export function estimateSystemPromptTokens(systemPrompt) {
|
|
43
|
+
return estimateTokens(systemPrompt);
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Count tokens from API usage response.
|
|
47
|
+
*/
|
|
48
|
+
export function getTokenCountFromUsage(usage) {
|
|
49
|
+
return (usage.input_tokens +
|
|
50
|
+
usage.output_tokens +
|
|
51
|
+
(usage.cache_creation_input_tokens || 0) +
|
|
52
|
+
(usage.cache_read_input_tokens || 0));
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Get the context window size for a model.
|
|
56
|
+
*/
|
|
57
|
+
export function getContextWindowSize(model) {
|
|
58
|
+
// Anthropic model context windows
|
|
59
|
+
if (model.includes('opus-4') && model.includes('1m'))
|
|
60
|
+
return 1_000_000;
|
|
61
|
+
if (model.includes('opus-4'))
|
|
62
|
+
return 200_000;
|
|
63
|
+
if (model.includes('sonnet-4'))
|
|
64
|
+
return 200_000;
|
|
65
|
+
if (model.includes('haiku-4'))
|
|
66
|
+
return 200_000;
|
|
67
|
+
if (model.includes('claude-3'))
|
|
68
|
+
return 200_000;
|
|
69
|
+
// OpenAI model context windows
|
|
70
|
+
if (model.includes('gpt-4o'))
|
|
71
|
+
return 128_000;
|
|
72
|
+
if (model.includes('gpt-4-turbo'))
|
|
73
|
+
return 128_000;
|
|
74
|
+
if (model.includes('gpt-4-1'))
|
|
75
|
+
return 1_000_000;
|
|
76
|
+
if (model.includes('gpt-4'))
|
|
77
|
+
return 128_000;
|
|
78
|
+
if (model.includes('gpt-3.5'))
|
|
79
|
+
return 16_385;
|
|
80
|
+
if (model.includes('o1'))
|
|
81
|
+
return 200_000;
|
|
82
|
+
if (model.includes('o3'))
|
|
83
|
+
return 200_000;
|
|
84
|
+
if (model.includes('o4'))
|
|
85
|
+
return 200_000;
|
|
86
|
+
// DeepSeek models
|
|
87
|
+
if (model.includes('deepseek'))
|
|
88
|
+
return 128_000;
|
|
89
|
+
// Default
|
|
90
|
+
return 200_000;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Auto-compact buffer: trigger compaction when within this many tokens of the limit.
|
|
94
|
+
*/
|
|
95
|
+
export const AUTOCOMPACT_BUFFER_TOKENS = 13_000;
|
|
96
|
+
/**
|
|
97
|
+
* Get the auto-compact threshold for a model.
|
|
98
|
+
*/
|
|
99
|
+
export function getAutoCompactThreshold(model) {
|
|
100
|
+
return getContextWindowSize(model) - AUTOCOMPACT_BUFFER_TOKENS;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Model pricing (USD per token).
|
|
104
|
+
*/
|
|
105
|
+
export const MODEL_PRICING = {
|
|
106
|
+
// Anthropic models
|
|
107
|
+
'claude-opus-4-6': { input: 15 / 1_000_000, output: 75 / 1_000_000 },
|
|
108
|
+
'claude-opus-4-5': { input: 15 / 1_000_000, output: 75 / 1_000_000 },
|
|
109
|
+
'claude-sonnet-4-6': { input: 3 / 1_000_000, output: 15 / 1_000_000 },
|
|
110
|
+
'claude-sonnet-4-5': { input: 3 / 1_000_000, output: 15 / 1_000_000 },
|
|
111
|
+
'claude-haiku-4-5': { input: 0.8 / 1_000_000, output: 4 / 1_000_000 },
|
|
112
|
+
'claude-3-5-sonnet': { input: 3 / 1_000_000, output: 15 / 1_000_000 },
|
|
113
|
+
'claude-3-5-haiku': { input: 0.8 / 1_000_000, output: 4 / 1_000_000 },
|
|
114
|
+
'claude-3-opus': { input: 15 / 1_000_000, output: 75 / 1_000_000 },
|
|
115
|
+
// OpenAI models
|
|
116
|
+
'gpt-4o': { input: 2.5 / 1_000_000, output: 10 / 1_000_000 },
|
|
117
|
+
'gpt-4o-mini': { input: 0.15 / 1_000_000, output: 0.6 / 1_000_000 },
|
|
118
|
+
'gpt-4-turbo': { input: 10 / 1_000_000, output: 30 / 1_000_000 },
|
|
119
|
+
'gpt-4-1': { input: 2 / 1_000_000, output: 8 / 1_000_000 },
|
|
120
|
+
'o1': { input: 15 / 1_000_000, output: 60 / 1_000_000 },
|
|
121
|
+
'o3': { input: 10 / 1_000_000, output: 40 / 1_000_000 },
|
|
122
|
+
'o4-mini': { input: 1.1 / 1_000_000, output: 4.4 / 1_000_000 },
|
|
123
|
+
// DeepSeek models
|
|
124
|
+
'deepseek-chat': { input: 0.27 / 1_000_000, output: 1.1 / 1_000_000 },
|
|
125
|
+
'deepseek-reasoner': { input: 0.55 / 1_000_000, output: 2.19 / 1_000_000 },
|
|
126
|
+
};
|
|
127
|
+
/**
|
|
128
|
+
* Estimate cost from usage and model.
|
|
129
|
+
*/
|
|
130
|
+
export function estimateCost(model, usage) {
|
|
131
|
+
const pricing = Object.entries(MODEL_PRICING).find(([key]) => model.includes(key))?.[1] ?? { input: 3 / 1_000_000, output: 15 / 1_000_000 };
|
|
132
|
+
return usage.input_tokens * pricing.input + usage.output_tokens * pricing.output;
|
|
133
|
+
}
|
|
134
|
+
//# sourceMappingURL=tokens.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tokens.js","sourceRoot":"","sources":["../../src/utils/tokens.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -12,7 +12,13 @@
|
|
|
12
12
|
"bugs": {
|
|
13
13
|
"url": "https://github.com/codeany-ai/open-agent-sdk-typescript/issues"
|
|
14
14
|
},
|
|
15
|
-
"version": "0.1
|
|
15
|
+
"version": "0.2.1",
|
|
16
|
+
"files": [
|
|
17
|
+
"dist",
|
|
18
|
+
"src",
|
|
19
|
+
"README.md",
|
|
20
|
+
"LICENSE"
|
|
21
|
+
],
|
|
16
22
|
"description": "Open-source Agent SDK. Runs the full agent loop in-process — no local CLI required. Deploy anywhere: cloud, serverless, Docker, CI/CD.",
|
|
17
23
|
"type": "module",
|
|
18
24
|
"main": "./dist/index.js",
|
package/src/agent.ts
CHANGED
|
@@ -8,6 +8,14 @@
|
|
|
8
8
|
* import { createAgent } from 'open-agent-sdk'
|
|
9
9
|
* const agent = createAgent({ model: 'claude-sonnet-4-6' })
|
|
10
10
|
* for await (const event of agent.query('Hello')) { ... }
|
|
11
|
+
*
|
|
12
|
+
* // OpenAI-compatible models
|
|
13
|
+
* const agent = createAgent({
|
|
14
|
+
* apiType: 'openai-completions',
|
|
15
|
+
* model: 'gpt-4o',
|
|
16
|
+
* apiKey: 'sk-...',
|
|
17
|
+
* baseURL: 'https://api.openai.com/v1',
|
|
18
|
+
* })
|
|
11
19
|
*/
|
|
12
20
|
|
|
13
21
|
import type {
|
|
@@ -17,7 +25,6 @@ import type {
|
|
|
17
25
|
ToolDefinition,
|
|
18
26
|
CanUseToolFn,
|
|
19
27
|
Message,
|
|
20
|
-
TokenUsage,
|
|
21
28
|
PermissionMode,
|
|
22
29
|
} from './types.js'
|
|
23
30
|
import { QueryEngine } from './engine.js'
|
|
@@ -29,7 +36,10 @@ import {
|
|
|
29
36
|
saveSession,
|
|
30
37
|
loadSession,
|
|
31
38
|
} from './session.js'
|
|
32
|
-
import type
|
|
39
|
+
import { createHookRegistry, type HookRegistry } from './hooks.js'
|
|
40
|
+
import { initBundledSkills } from './skills/index.js'
|
|
41
|
+
import { createProvider, type LLMProvider, type ApiType } from './providers/index.js'
|
|
42
|
+
import type { NormalizedMessageParam } from './providers/types.js'
|
|
33
43
|
|
|
34
44
|
// --------------------------------------------------------------------------
|
|
35
45
|
// Agent class
|
|
@@ -39,14 +49,17 @@ export class Agent {
|
|
|
39
49
|
private cfg: AgentOptions
|
|
40
50
|
private toolPool: ToolDefinition[]
|
|
41
51
|
private modelId: string
|
|
52
|
+
private apiType: ApiType
|
|
42
53
|
private apiCredentials: { key?: string; baseUrl?: string }
|
|
54
|
+
private provider: LLMProvider
|
|
43
55
|
private mcpLinks: MCPConnection[] = []
|
|
44
|
-
private history:
|
|
56
|
+
private history: NormalizedMessageParam[] = []
|
|
45
57
|
private messageLog: Message[] = []
|
|
46
58
|
private setupDone: Promise<void>
|
|
47
59
|
private sid: string
|
|
48
60
|
private abortCtrl: AbortController | null = null
|
|
49
61
|
private currentEngine: QueryEngine | null = null
|
|
62
|
+
private hookRegistry: HookRegistry
|
|
50
63
|
|
|
51
64
|
constructor(options: AgentOptions = {}) {
|
|
52
65
|
// Shallow copy to avoid mutating caller's object
|
|
@@ -57,13 +70,38 @@ export class Agent {
|
|
|
57
70
|
this.modelId = this.cfg.model ?? this.readEnv('CODEANY_MODEL') ?? 'claude-sonnet-4-6'
|
|
58
71
|
this.sid = this.cfg.sessionId ?? crypto.randomUUID()
|
|
59
72
|
|
|
60
|
-
//
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
73
|
+
// Resolve API type
|
|
74
|
+
this.apiType = this.resolveApiType()
|
|
75
|
+
|
|
76
|
+
// Create LLM provider
|
|
77
|
+
this.provider = createProvider(this.apiType, {
|
|
78
|
+
apiKey: this.apiCredentials.key,
|
|
79
|
+
baseURL: this.apiCredentials.baseUrl,
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
// Initialize bundled skills
|
|
83
|
+
initBundledSkills()
|
|
84
|
+
|
|
85
|
+
// Build hook registry from options
|
|
86
|
+
this.hookRegistry = createHookRegistry()
|
|
87
|
+
if (this.cfg.hooks) {
|
|
88
|
+
// Convert AgentOptions hooks format to HookConfig
|
|
89
|
+
for (const [event, defs] of Object.entries(this.cfg.hooks)) {
|
|
90
|
+
for (const def of defs) {
|
|
91
|
+
for (const handler of def.hooks) {
|
|
92
|
+
this.hookRegistry.register(event as any, {
|
|
93
|
+
matcher: def.matcher,
|
|
94
|
+
timeout: def.timeout,
|
|
95
|
+
handler: async (input) => {
|
|
96
|
+
const result = await handler(input, input.toolUseId || '', {
|
|
97
|
+
signal: this.abortCtrl?.signal || new AbortController().signal,
|
|
98
|
+
})
|
|
99
|
+
return result || undefined
|
|
100
|
+
},
|
|
101
|
+
})
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
67
105
|
}
|
|
68
106
|
|
|
69
107
|
// Build tool pool from options (supports ToolDefinition[], string[], or preset)
|
|
@@ -73,6 +111,41 @@ export class Agent {
|
|
|
73
111
|
this.setupDone = this.setup()
|
|
74
112
|
}
|
|
75
113
|
|
|
114
|
+
/**
|
|
115
|
+
* Resolve API type from options, env, or model name heuristic.
|
|
116
|
+
*/
|
|
117
|
+
private resolveApiType(): ApiType {
|
|
118
|
+
// Explicit option
|
|
119
|
+
if (this.cfg.apiType) return this.cfg.apiType
|
|
120
|
+
|
|
121
|
+
// Env var
|
|
122
|
+
const envType =
|
|
123
|
+
this.cfg.env?.CODEANY_API_TYPE ??
|
|
124
|
+
this.readEnv('CODEANY_API_TYPE')
|
|
125
|
+
if (envType === 'openai-completions' || envType === 'anthropic-messages') {
|
|
126
|
+
return envType
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// Heuristic from model name
|
|
130
|
+
const model = this.modelId.toLowerCase()
|
|
131
|
+
if (
|
|
132
|
+
model.includes('gpt-') ||
|
|
133
|
+
model.includes('o1') ||
|
|
134
|
+
model.includes('o3') ||
|
|
135
|
+
model.includes('o4') ||
|
|
136
|
+
model.includes('deepseek') ||
|
|
137
|
+
model.includes('qwen') ||
|
|
138
|
+
model.includes('yi-') ||
|
|
139
|
+
model.includes('glm') ||
|
|
140
|
+
model.includes('mistral') ||
|
|
141
|
+
model.includes('gemma')
|
|
142
|
+
) {
|
|
143
|
+
return 'openai-completions'
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
return 'anthropic-messages'
|
|
147
|
+
}
|
|
148
|
+
|
|
76
149
|
/** Pick API key and base URL from options or CODEANY_* env vars. */
|
|
77
150
|
private pickCredentials(): { key?: string; baseUrl?: string } {
|
|
78
151
|
const envMap = this.cfg.env
|
|
@@ -208,12 +281,21 @@ export class Agent {
|
|
|
208
281
|
}
|
|
209
282
|
}
|
|
210
283
|
|
|
284
|
+
// Recreate provider if overrides change credentials or apiType
|
|
285
|
+
let provider = this.provider
|
|
286
|
+
if (overrides?.apiType || overrides?.apiKey || overrides?.baseURL) {
|
|
287
|
+
const resolvedApiType = overrides.apiType ?? this.apiType
|
|
288
|
+
provider = createProvider(resolvedApiType, {
|
|
289
|
+
apiKey: overrides.apiKey ?? this.apiCredentials.key,
|
|
290
|
+
baseURL: overrides.baseURL ?? this.apiCredentials.baseUrl,
|
|
291
|
+
})
|
|
292
|
+
}
|
|
293
|
+
|
|
211
294
|
// Create query engine with current conversation state
|
|
212
295
|
const engine = new QueryEngine({
|
|
213
296
|
cwd,
|
|
214
297
|
model: opts.model || this.modelId,
|
|
215
|
-
|
|
216
|
-
baseURL: this.apiCredentials.baseUrl,
|
|
298
|
+
provider,
|
|
217
299
|
tools,
|
|
218
300
|
systemPrompt,
|
|
219
301
|
appendSystemPrompt,
|
|
@@ -226,6 +308,8 @@ export class Agent {
|
|
|
226
308
|
includePartialMessages: opts.includePartialMessages ?? false,
|
|
227
309
|
abortSignal: this.abortCtrl.signal,
|
|
228
310
|
agents: opts.agents,
|
|
311
|
+
hookRegistry: this.hookRegistry,
|
|
312
|
+
sessionId: this.sid,
|
|
229
313
|
})
|
|
230
314
|
this.currentEngine = engine
|
|
231
315
|
|
|
@@ -279,9 +363,9 @@ export class Agent {
|
|
|
279
363
|
switch (ev.type) {
|
|
280
364
|
case 'assistant': {
|
|
281
365
|
// Extract the last assistant text (multi-turn: only final answer matters)
|
|
282
|
-
const fragments = ev.message.content
|
|
283
|
-
.filter((c
|
|
284
|
-
.map((c) => c.text)
|
|
366
|
+
const fragments = (ev.message.content as any[])
|
|
367
|
+
.filter((c: any) => c.type === 'text')
|
|
368
|
+
.map((c: any) => c.text)
|
|
285
369
|
if (fragments.length) collected.text = fragments.join('')
|
|
286
370
|
break
|
|
287
371
|
}
|
|
@@ -359,6 +443,13 @@ export class Agent {
|
|
|
359
443
|
return this.sid
|
|
360
444
|
}
|
|
361
445
|
|
|
446
|
+
/**
|
|
447
|
+
* Get the current API type.
|
|
448
|
+
*/
|
|
449
|
+
getApiType(): ApiType {
|
|
450
|
+
return this.apiType
|
|
451
|
+
}
|
|
452
|
+
|
|
362
453
|
/**
|
|
363
454
|
* Stop a background task.
|
|
364
455
|
*/
|