@meetopenbot/cursor 0.0.4 → 0.0.6
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/dist/runtime.js +9 -7
- package/dist/stream.js +28 -15
- package/package.json +2 -2
package/dist/runtime.js
CHANGED
|
@@ -1,15 +1,17 @@
|
|
|
1
|
-
import { missingSecretMessage } from '@meetopenbot/plugin-sdk';
|
|
1
|
+
import { missingSecretMessage, textReply, } from '@meetopenbot/plugin-sdk';
|
|
2
2
|
import { CURSOR_API_KEY_ENV_VAR, resolveConfig } from './config.js';
|
|
3
3
|
import { getOrCreateCursorAgent, StaleAgentSessionError } from './session.js';
|
|
4
4
|
import { runCursorPrompt } from './stream.js';
|
|
5
|
-
export async function runCursorTurn({ prompt, handlerCtx, context, }) {
|
|
5
|
+
export async function* runCursorTurn({ prompt, handlerCtx, context, }) {
|
|
6
6
|
const channelCwd = handlerCtx.state.channelDetails?.cwd;
|
|
7
7
|
const config = resolveConfig(context, channelCwd);
|
|
8
8
|
if (!config.apiKey) {
|
|
9
|
-
|
|
9
|
+
yield textReply(missingSecretMessage(CURSOR_API_KEY_ENV_VAR));
|
|
10
|
+
return;
|
|
10
11
|
}
|
|
11
12
|
if (config.runtime === 'local' && !config.cwd) {
|
|
12
|
-
|
|
13
|
+
yield textReply('Local Cursor agents need a working directory. Configure a channel `cwd`.');
|
|
14
|
+
return;
|
|
13
15
|
}
|
|
14
16
|
let agentHandle = await getOrCreateCursorAgent({
|
|
15
17
|
config,
|
|
@@ -17,7 +19,7 @@ export async function runCursorTurn({ prompt, handlerCtx, context, }) {
|
|
|
17
19
|
storage: context.storage,
|
|
18
20
|
});
|
|
19
21
|
try {
|
|
20
|
-
|
|
22
|
+
yield* runCursorPrompt(agentHandle.agent, prompt, config, agentHandle.wasResumed);
|
|
21
23
|
}
|
|
22
24
|
catch (error) {
|
|
23
25
|
if (!(error instanceof StaleAgentSessionError))
|
|
@@ -28,10 +30,10 @@ export async function runCursorTurn({ prompt, handlerCtx, context, }) {
|
|
|
28
30
|
storage: context.storage,
|
|
29
31
|
forceNew: true,
|
|
30
32
|
});
|
|
31
|
-
|
|
33
|
+
yield* runCursorPrompt(agentHandle.agent, prompt, config, agentHandle.wasResumed);
|
|
32
34
|
}
|
|
33
35
|
}
|
|
34
36
|
export function mapCursorError(error) {
|
|
35
37
|
const message = error instanceof Error ? error.message : String(error);
|
|
36
|
-
return
|
|
38
|
+
return textReply(`Cursor error: ${message}`);
|
|
37
39
|
}
|
package/dist/stream.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { emitTextReplies, textReply, } from '@meetopenbot/plugin-sdk';
|
|
1
2
|
import { buildModelSelection } from './config.js';
|
|
2
3
|
import { StaleAgentSessionError } from './session.js';
|
|
3
4
|
const assistantText = (event) => {
|
|
@@ -8,31 +9,43 @@ const assistantText = (event) => {
|
|
|
8
9
|
.map((block) => block.text)
|
|
9
10
|
.join('');
|
|
10
11
|
};
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
export const classifyCursorEvent = (event) => {
|
|
13
|
+
if (event.type === 'assistant') {
|
|
14
|
+
const text = assistantText(event);
|
|
15
|
+
return text ? { type: 'delta', text } : { type: 'skip' };
|
|
16
|
+
}
|
|
17
|
+
if (event.type === 'tool_call') {
|
|
18
|
+
if (event.status === 'running') {
|
|
19
|
+
return { type: 'tool_call', id: event.call_id, name: event.name, input: event.args };
|
|
20
|
+
}
|
|
21
|
+
return {
|
|
22
|
+
type: 'tool_result',
|
|
23
|
+
id: event.call_id,
|
|
24
|
+
name: event.name,
|
|
25
|
+
input: event.args,
|
|
26
|
+
output: event.result,
|
|
27
|
+
error: event.status === 'error',
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
if (event.type === 'usage')
|
|
31
|
+
return { type: 'flush' };
|
|
32
|
+
return { type: 'skip' };
|
|
33
|
+
};
|
|
34
|
+
/** Run a Cursor prompt and yield each completed assistant turn and tool widget. */
|
|
35
|
+
export async function* runCursorPrompt(agent, prompt, config, wasResumed) {
|
|
14
36
|
const run = await agent.send(prompt, {
|
|
15
37
|
...(config.mode ? { mode: config.mode } : {}),
|
|
16
38
|
model: buildModelSelection(config),
|
|
17
39
|
});
|
|
18
|
-
|
|
19
|
-
const text = assistantText(event);
|
|
20
|
-
if (text)
|
|
21
|
-
collected += text;
|
|
22
|
-
}
|
|
40
|
+
yield* emitTextReplies(run.stream(), classifyCursorEvent, { groupId: 'cursor:tools' });
|
|
23
41
|
const result = await run.wait();
|
|
24
|
-
const parts = [];
|
|
25
|
-
const finalText = (result.result ?? collected).trim();
|
|
26
|
-
if (finalText)
|
|
27
|
-
parts.push(finalText);
|
|
28
42
|
if (result.status === 'error') {
|
|
29
43
|
if (wasResumed && (result.durationMs ?? 0) < 2000) {
|
|
30
44
|
throw new StaleAgentSessionError('Resumed Cursor agent session is stale or expired.');
|
|
31
45
|
}
|
|
32
|
-
|
|
46
|
+
yield textReply(`Cursor error: run finished with status ${result.status}.`);
|
|
33
47
|
}
|
|
34
48
|
else if (result.status === 'cancelled') {
|
|
35
|
-
|
|
49
|
+
yield textReply('Cursor run cancelled.');
|
|
36
50
|
}
|
|
37
|
-
return parts.join('\n\n');
|
|
38
51
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@meetopenbot/cursor",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.6",
|
|
4
4
|
"description": "OpenBot agent plugin powered by the Cursor SDK.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"license": "MIT",
|
|
21
21
|
"dependencies": {
|
|
22
22
|
"@cursor/sdk": "^1.0.18",
|
|
23
|
-
"@meetopenbot/plugin-sdk": "^0.
|
|
23
|
+
"@meetopenbot/plugin-sdk": "^0.5.0"
|
|
24
24
|
},
|
|
25
25
|
"devDependencies": {
|
|
26
26
|
"@types/node": "^25.9.2",
|