@surph_ai/sdk 0.0.21 → 0.0.23
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/deploy/index.js +0 -1
- package/deploy/tool-handler.js +2 -2
- package/index.js +1 -1
- package/package.json +2 -1
- package/scaffold/tool/tools/index.ts +11 -4
- package/toolserver/chat.js +11 -8
- package/toolserver/routes/tool.js +5 -11
- package/types.d.ts +63 -0
package/deploy/index.js
CHANGED
package/deploy/tool-handler.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import tool from './dist/tools/index.js';
|
|
2
2
|
|
|
3
3
|
export const handler = async (event) => {
|
|
4
|
-
const { args = {} } = event;
|
|
4
|
+
const { args = {}, context = null, user = null } = event;
|
|
5
5
|
let payload = null;
|
|
6
6
|
try {
|
|
7
|
-
payload = await tool(args);
|
|
7
|
+
payload = await tool({ args, context, user });
|
|
8
8
|
} catch (error) {
|
|
9
9
|
payload = error instanceof Error ? error.message : String(error);
|
|
10
10
|
}
|
package/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,9 +1,16 @@
|
|
|
1
1
|
// Your tools code goes here. When ready, export
|
|
2
2
|
// the tool name in exports at bottom of this file
|
|
3
3
|
// as shown in this demo code:
|
|
4
|
+
import type { ToolHandler, ToolContext, User } from '@surph_ai/sdk';
|
|
4
5
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
}
|
|
6
|
+
type YourToolArgs = {
|
|
7
|
+
// your custom tool args goes here
|
|
8
|
+
};
|
|
8
9
|
|
|
9
|
-
|
|
10
|
+
type ToolArgs = YourToolArgs;
|
|
11
|
+
|
|
12
|
+
const handler: ToolHandler<ToolArgs> = async ({ args, user, context }) => {
|
|
13
|
+
// your custom tool code goes here
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export default handler;
|
package/toolserver/chat.js
CHANGED
|
@@ -333,7 +333,7 @@ var require_main = __commonJS({
|
|
|
333
333
|
lastError = e;
|
|
334
334
|
}
|
|
335
335
|
}
|
|
336
|
-
|
|
336
|
+
_log(`injecting env (${keysCount}) from ${shortPaths.join(",")} ${dim(`-- tip: ${_getRandomTip()}`)}`);
|
|
337
337
|
}
|
|
338
338
|
if (lastError) {
|
|
339
339
|
return { parsed: parsedAll, error: lastError };
|
|
@@ -46362,7 +46362,6 @@ var require_executeDesktopTool = __commonJS({
|
|
|
46362
46362
|
try {
|
|
46363
46363
|
VectorDBManager = require_VectorDBManager();
|
|
46364
46364
|
} catch (err) {
|
|
46365
|
-
// console.log("[executeDesktopTool] VectorDBManager not available:", err.message);
|
|
46366
46365
|
VectorDBManager = null;
|
|
46367
46366
|
}
|
|
46368
46367
|
function resolvePath(filePath, projectPath) {
|
|
@@ -46556,7 +46555,7 @@ var require_customTool = __commonJS({
|
|
|
46556
46555
|
if (!Array.isArray(userTools)) return null;
|
|
46557
46556
|
return userTools.find((t) => t && t.name === name) || null;
|
|
46558
46557
|
}
|
|
46559
|
-
async function executeCustomTool({ name, args, user, tools }) {
|
|
46558
|
+
async function executeCustomTool({ name, args, user, tools, contextSlug = null }) {
|
|
46560
46559
|
const definition = findCustomToolDefinition(tools, name);
|
|
46561
46560
|
if (!definition) {
|
|
46562
46561
|
return { error: `Custom tool '${name}' not found on user profile` };
|
|
@@ -46570,9 +46569,10 @@ var require_customTool = __commonJS({
|
|
|
46570
46569
|
headers: { "Content-Type": "application/json" },
|
|
46571
46570
|
body: JSON.stringify({
|
|
46572
46571
|
name,
|
|
46573
|
-
args: args || {},
|
|
46574
46572
|
tool: definition,
|
|
46575
|
-
|
|
46573
|
+
context: contextSlug || null,
|
|
46574
|
+
args: args || {},
|
|
46575
|
+
user: user ? { id: user.id || user._id, username: user.username, oauth: user.oauth || {} } : null
|
|
46576
46576
|
}),
|
|
46577
46577
|
signal: controller.signal
|
|
46578
46578
|
});
|
|
@@ -46658,7 +46658,7 @@ var require_executeTool = __commonJS({
|
|
|
46658
46658
|
// 'deleteFile'
|
|
46659
46659
|
]);
|
|
46660
46660
|
var executeTool = async (name, args, context = {}) => {
|
|
46661
|
-
const { runtime = "remote", session } = context;
|
|
46661
|
+
const { runtime = "remote", session, contextSlug = null } = context;
|
|
46662
46662
|
console.log(`
|
|
46663
46663
|
|
|
46664
46664
|
server/chat/executeTool.js: EXECUTE TOOL: ${session}
|
|
@@ -46709,7 +46709,7 @@ server/chat/executeTool.js: EXECUTE TOOL: ${session}
|
|
|
46709
46709
|
default: {
|
|
46710
46710
|
const userTools = session?.user?.tools;
|
|
46711
46711
|
if (findCustomToolDefinition(userTools, name)) {
|
|
46712
|
-
return await executeCustomTool({ name, args, user: session?.user, tools: userTools });
|
|
46712
|
+
return await executeCustomTool({ name, args, user: session?.user, tools: userTools, contextSlug });
|
|
46713
46713
|
}
|
|
46714
46714
|
return { error: `Unknown tool: ${name}` };
|
|
46715
46715
|
}
|
|
@@ -94676,6 +94676,9 @@ Always use absolute paths for file operations. When the user asks to create a fi
|
|
|
94676
94676
|
runtime: "remote",
|
|
94677
94677
|
projectPath: workingDirectory,
|
|
94678
94678
|
session,
|
|
94679
|
+
// Currently-selected context slug, forwarded to custom tools so their RPC
|
|
94680
|
+
// knows which context the invocation was scoped to.
|
|
94681
|
+
contextSlug: params?.context?.slug || params?.currentContextSlug || null,
|
|
94679
94682
|
// Passed to tools that emit real-time SSE frames (e.g. searchContext
|
|
94680
94683
|
// → `references.added`). Null on paths where no stream is bound.
|
|
94681
94684
|
outputStream
|
|
@@ -94770,7 +94773,7 @@ ${STREAM_LABEL} provider:${provider} tide:${params?.tide ? "present" : "none"} s
|
|
|
94770
94773
|
});
|
|
94771
94774
|
|
|
94772
94775
|
// server/sdk.js
|
|
94773
|
-
require_main().config();
|
|
94776
|
+
require_main().config({ quiet: true });
|
|
94774
94777
|
process.env.SURPH_CUSTOM_TOOL_RPC = "http://localhost:5000";
|
|
94775
94778
|
var express = require_express2();
|
|
94776
94779
|
var cors = require_lib3();
|
|
@@ -16,12 +16,12 @@ const loadTool = () => import(toolsPath).then((mod) => mod.default)
|
|
|
16
16
|
|
|
17
17
|
const router = Router()
|
|
18
18
|
|
|
19
|
-
const handler = async (
|
|
20
|
-
|
|
19
|
+
const handler = async (event, tool) => {
|
|
20
|
+
const { args, context, user } = event
|
|
21
21
|
let payload = null
|
|
22
22
|
let errorMsg = null
|
|
23
23
|
try {
|
|
24
|
-
payload = await tool(args)
|
|
24
|
+
payload = await tool({ args, context, user })
|
|
25
25
|
} catch (error) {
|
|
26
26
|
errorMsg = error instanceof Error ? error.message : String(error)
|
|
27
27
|
} finally {
|
|
@@ -88,22 +88,16 @@ router.get('/test', async (req, res, next) => {
|
|
|
88
88
|
})
|
|
89
89
|
|
|
90
90
|
router.post('/custom', async (req, res, next) => {
|
|
91
|
-
// console.log('TOOL CALL: ' + JSON.stringify(req.body))
|
|
92
91
|
try {
|
|
93
|
-
const { name, args, tool, user = null } = req.body;
|
|
94
|
-
// console.log('TOOL CALL: ' + name)
|
|
95
|
-
// console.log('TOOL ARGS: ' + JSON.stringify(args))
|
|
96
|
-
|
|
92
|
+
const { name, args, tool, user = null, context = null } = req.body;
|
|
97
93
|
if (process.env.SURPH_TOOL !== tool.slug) {
|
|
98
94
|
throw new Error(`Invalid tool ${tool.slug}. Check .env file.`)
|
|
99
95
|
}
|
|
100
96
|
|
|
101
97
|
const tools = await loadTool()
|
|
102
|
-
const response = await handler(args, tools)
|
|
103
|
-
// console.log('TOOL RESP: ' + JSON.stringify(response))
|
|
98
|
+
const response = await handler({ args, context, user }, tools)
|
|
104
99
|
res.json({ response })
|
|
105
100
|
} catch (error) {
|
|
106
|
-
// console.log('TOOL ERR: ' + error.message)
|
|
107
101
|
res.json({
|
|
108
102
|
response: {
|
|
109
103
|
success: false,
|
package/types.d.ts
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
// Type definitions for @surph_ai/sdk
|
|
2
|
+
// These describe the runtime contract the tool server hands to each tool's default export.
|
|
3
|
+
|
|
4
|
+
export type OAuthProvider = 'google' | 'github' | (string & {});
|
|
5
|
+
|
|
6
|
+
export interface GoogleOAuth {
|
|
7
|
+
accessToken: string;
|
|
8
|
+
refreshToken?: string;
|
|
9
|
+
/** ISO-8601 timestamp for when accessToken expires. */
|
|
10
|
+
expiresAt: string;
|
|
11
|
+
/** OAuth scopes granted by the user. */
|
|
12
|
+
scopes: string[];
|
|
13
|
+
/** ISO-8601 timestamp for when the user first connected the provider. */
|
|
14
|
+
connectedAt: string;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface UserOAuth {
|
|
18
|
+
google?: GoogleOAuth;
|
|
19
|
+
[provider: string]: unknown;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export interface UserAuth {
|
|
23
|
+
type: OAuthProvider;
|
|
24
|
+
/** Provider-issued stable identifier for the user (e.g. Google 'sub'). */
|
|
25
|
+
id: string;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export interface User {
|
|
29
|
+
_id: string;
|
|
30
|
+
firstName?: string;
|
|
31
|
+
lastName?: string;
|
|
32
|
+
email: string;
|
|
33
|
+
username: string;
|
|
34
|
+
avatar?: string;
|
|
35
|
+
tags?: string[];
|
|
36
|
+
following?: string[];
|
|
37
|
+
notifications?: unknown[];
|
|
38
|
+
type?: 'claimed' | 'anonymous' | (string & {});
|
|
39
|
+
auth?: UserAuth;
|
|
40
|
+
timestamp?: string;
|
|
41
|
+
lastVisit?: string;
|
|
42
|
+
identifiers?: string[];
|
|
43
|
+
tools?: string[];
|
|
44
|
+
oauth?: UserOAuth;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Per-invocation context. Currently opaque — populated by the caller (chat
|
|
49
|
+
* server, deployed harness, etc.). Cast to a more specific shape inside the
|
|
50
|
+
* tool if you know what your caller sends.
|
|
51
|
+
*/
|
|
52
|
+
export type ToolContext = Record<string, unknown> | null;
|
|
53
|
+
|
|
54
|
+
export interface ToolHandlerInput<TArgs = Record<string, unknown>> {
|
|
55
|
+
args: TArgs;
|
|
56
|
+
context: ToolContext;
|
|
57
|
+
user: User;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export type ToolHandler<
|
|
61
|
+
TArgs = Record<string, unknown>,
|
|
62
|
+
TResult = unknown,
|
|
63
|
+
> = (input: ToolHandlerInput<TArgs>) => Promise<TResult> | TResult;
|