@cursor/july 0.1.17 → 0.1.18
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/channels/slack/cursor-account.d.ts.map +1 -1
- package/dist/channels/slack/cursor-account.js +1 -1
- package/dist/channels/slack/dispatch.d.ts.map +1 -1
- package/dist/channels/slack/dispatch.js +4 -1
- package/dist/channels/slack/inbound.d.ts.map +1 -1
- package/dist/channels/slack/inbound.js +6 -1
- package/dist/channels/slack/index.d.ts +1 -0
- package/dist/channels/slack/index.d.ts.map +1 -1
- package/dist/channels/slack/index.js +1 -0
- package/dist/channels/slack/init.d.ts.map +1 -1
- package/dist/channels/slack/init.js +4 -1
- package/dist/channels/slack/interactive.d.ts.map +1 -1
- package/dist/channels/slack/interactive.js +1 -0
- package/dist/channels/slack/manifest.d.ts +10 -0
- package/dist/channels/slack/manifest.d.ts.map +1 -1
- package/dist/channels/slack/manifest.js +33 -14
- package/dist/channels/slack/message-body.d.ts +13 -0
- package/dist/channels/slack/message-body.d.ts.map +1 -0
- package/dist/channels/slack/message-body.js +82 -0
- package/dist/channels/slack/thread-context.d.ts +0 -2
- package/dist/channels/slack/thread-context.d.ts.map +1 -1
- package/dist/channels/slack/thread-context.js +1 -65
- package/dist/channels/slack/types.d.ts +16 -1
- package/dist/channels/slack/types.d.ts.map +1 -1
- package/dist/docs/404.html +2 -2
- package/dist/docs/ab.html +3 -3
- package/dist/docs/assets/{app.BbEXr2KO.js → app.BR5EdVSq.js} +1 -1
- package/dist/docs/assets/chunks/@localSearchIndexroot.BOzkeUi8.js +1 -0
- package/dist/docs/assets/chunks/{VPLocalSearchBox.DBEi4HDp.js → VPLocalSearchBox.CNCzfUKC.js} +1 -1
- package/dist/docs/assets/chunks/{theme.DGfptcHw.js → theme.CwKvMSWv.js} +2 -2
- package/dist/docs/assets/{example-agents_security-reviewer.md.BZSNycMf.js → example-agents_security-reviewer.md.Dhj_m7_B.js} +1 -1
- package/dist/docs/building-with-agents.html +3 -3
- package/dist/docs/concepts.html +3 -3
- package/dist/docs/deployment.html +3 -3
- package/dist/docs/evals.html +3 -3
- package/dist/docs/example-agents/approval-buddy.html +3 -3
- package/dist/docs/example-agents/benny.html +3 -3
- package/dist/docs/example-agents/bugbot.html +3 -3
- package/dist/docs/example-agents/codebase-wiki.html +3 -3
- package/dist/docs/example-agents/codeowners-review.html +3 -3
- package/dist/docs/example-agents/concierge.html +3 -3
- package/dist/docs/example-agents/fsd.html +3 -3
- package/dist/docs/example-agents/index.html +3 -3
- package/dist/docs/example-agents/knowledge-base.html +3 -3
- package/dist/docs/example-agents/oncall.html +3 -3
- package/dist/docs/example-agents/security-reviewer.html +5 -5
- package/dist/docs/example-agents/slack-agent.html +3 -3
- package/dist/docs/example-agents/weather-agent.html +3 -3
- package/dist/docs/guides/agent-to-agent.html +3 -3
- package/dist/docs/guides/cloud-runtime.html +3 -3
- package/dist/docs/guides/github.html +3 -3
- package/dist/docs/guides/human-in-the-loop.html +3 -3
- package/dist/docs/guides/mcp-oauth.html +3 -3
- package/dist/docs/guides/slack.html +3 -3
- package/dist/docs/guides/webhooks.html +3 -3
- package/dist/docs/hashmap.json +1 -1
- package/dist/docs/hillclimbing.html +3 -3
- package/dist/docs/index.html +3 -3
- package/dist/docs/quickstart.html +3 -3
- package/dist/docs/reference/agent-config.html +3 -3
- package/dist/docs/reference/channels.html +3 -3
- package/dist/docs/reference/cli.html +3 -3
- package/dist/docs/reference/connections.html +3 -3
- package/dist/docs/reference/hooks.html +3 -3
- package/dist/docs/reference/http-api.html +3 -3
- package/dist/docs/reference/instructions.html +3 -3
- package/dist/docs/reference/playground.html +3 -3
- package/dist/docs/reference/project-layout.html +3 -3
- package/dist/docs/reference/prompt.html +3 -3
- package/dist/docs/reference/schedules.html +3 -3
- package/dist/docs/reference/sessions.html +3 -3
- package/dist/docs/reference/skills.html +3 -3
- package/dist/docs/reference/subagents.html +3 -3
- package/dist/docs/reference/tools.html +3 -3
- package/dist/docs/scaffolding-agents.html +3 -3
- package/dist/docs/storage.html +3 -3
- package/dist/docs/troubleshooting.html +3 -3
- package/dist/internal/builtin-tools/index.d.ts +10 -0
- package/dist/internal/builtin-tools/index.d.ts.map +1 -0
- package/dist/internal/builtin-tools/index.js +27 -0
- package/dist/internal/builtin-tools/reminders.d.ts +9 -0
- package/dist/internal/builtin-tools/reminders.d.ts.map +1 -0
- package/dist/internal/builtin-tools/reminders.js +138 -0
- package/dist/internal/cli-slack.d.ts.map +1 -1
- package/dist/internal/cli-slack.js +36 -15
- package/dist/internal/cursor-event-relay.d.ts +30 -0
- package/dist/internal/cursor-event-relay.d.ts.map +1 -1
- package/dist/internal/cursor-event-relay.js +37 -0
- package/dist/internal/discovery.d.ts.map +1 -1
- package/dist/internal/discovery.js +41 -0
- package/dist/internal/reminder-runner.d.ts +7 -0
- package/dist/internal/reminder-runner.d.ts.map +1 -1
- package/dist/internal/reminder-runner.js +21 -0
- package/dist/internal/sdk-runner.d.ts +15 -0
- package/dist/internal/sdk-runner.d.ts.map +1 -1
- package/dist/internal/sdk-runner.js +113 -13
- package/dist/internal/server.d.ts.map +1 -1
- package/dist/internal/server.js +1 -0
- package/dist/internal/session-engine.d.ts.map +1 -1
- package/dist/internal/session-engine.js +9 -0
- package/dist/internal/slack-provision-client.d.ts +6 -3
- package/dist/internal/slack-provision-client.d.ts.map +1 -1
- package/dist/internal/slack-provision-client.js +5 -3
- package/dist/playground/assets/{index-DNqirsrK.js → index-DRjS5klQ.js} +42 -42
- package/dist/playground/assets/index-TCDs-UhZ.css +1 -0
- package/dist/playground/index.html +2 -2
- package/dist/types.d.ts +28 -0
- package/dist/types.d.ts.map +1 -1
- package/docs/example-agents/security-reviewer.md +1 -1
- package/package.json +1 -1
- package/skills/setup-slack/SKILL.md +4 -0
- package/src/channels/slack/cursor-account.ts +1 -0
- package/src/channels/slack/dispatch.ts +3 -1
- package/src/channels/slack/inbound.ts +6 -1
- package/src/channels/slack/index.ts +1 -0
- package/src/channels/slack/init.ts +3 -0
- package/src/channels/slack/interactive.ts +1 -0
- package/src/channels/slack/manifest.ts +34 -6
- package/src/channels/slack/message-body.ts +90 -0
- package/src/channels/slack/thread-context.ts +1 -69
- package/src/channels/slack/types.ts +16 -1
- package/src/internal/builtin-tools/index.ts +40 -0
- package/src/internal/builtin-tools/reminders.ts +158 -0
- package/src/internal/cli-slack.ts +38 -14
- package/src/internal/cursor-event-relay.ts +67 -0
- package/src/internal/discovery.ts +52 -0
- package/src/internal/reminder-runner.ts +30 -0
- package/src/internal/sdk-runner.ts +131 -13
- package/src/internal/server.ts +2 -0
- package/src/internal/session-engine.ts +14 -0
- package/src/internal/slack-provision-client.ts +7 -3
- package/src/types.ts +33 -0
- package/dist/docs/assets/chunks/@localSearchIndexroot.DCBsrfwP.js +0 -1
- package/dist/playground/assets/index-CidizGZv.css +0 -1
- /package/dist/docs/assets/{example-agents_security-reviewer.md.BZSNycMf.lean.js → example-agents_security-reviewer.md.Dhj_m7_B.lean.js} +0 -0
|
@@ -86,16 +86,90 @@ export interface CursorSdkRunnerOptions {
|
|
|
86
86
|
logger?: (line: string) => void;
|
|
87
87
|
}
|
|
88
88
|
|
|
89
|
+
/**
|
|
90
|
+
* How long one SDK agent handle (and the Connect transport inside it) may be
|
|
91
|
+
* reused before the runner retires it.
|
|
92
|
+
*
|
|
93
|
+
* The transport exchanges the account API key for a short-lived access token
|
|
94
|
+
* (`SessionType.API_KEY_TOKEN`, 60 minutes) once per handle, and has no
|
|
95
|
+
* reliable refresh: an Unauthenticated rejection on the agent's streaming RPC
|
|
96
|
+
* surfaces while the stream is being read — outside the transport's
|
|
97
|
+
* request-time 401 retry — so an expired token gets replayed on every
|
|
98
|
+
* subsequent turn until the handle is rebuilt. Long-lived sessions (watch
|
|
99
|
+
* wakes, crons) hit this at the ~60 minute mark and then fail forever.
|
|
100
|
+
* Retiring the handle comfortably before the token can expire keeps them
|
|
101
|
+
* healthy: `Agent.resume` rehydrates the same conversation from the runner
|
|
102
|
+
* store on a fresh transport, so recycling costs only transport warmth.
|
|
103
|
+
*/
|
|
104
|
+
const MAX_AGENT_HANDLE_AGE_MS = 45 * 60 * 1000;
|
|
105
|
+
|
|
106
|
+
interface CachedAgentHandle {
|
|
107
|
+
agent: Promise<SDKAgent>;
|
|
108
|
+
openedAtMs: number;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* The backend's `NotLoggedIn` copy ("Authentication error" title, "try
|
|
113
|
+
* logging out and back in." detail) as it surfaces through SDK RunResults.
|
|
114
|
+
* Deliberately narrow: this gates a one-shot in-place retry, and matching
|
|
115
|
+
* broader error text would retry turns that a fresh transport cannot fix.
|
|
116
|
+
*/
|
|
117
|
+
export function isAuthErrorMessage(message: string | undefined): boolean {
|
|
118
|
+
if (message === undefined) {
|
|
119
|
+
return false;
|
|
120
|
+
}
|
|
121
|
+
return /authentication error|try logging out and back in/i.test(message);
|
|
122
|
+
}
|
|
123
|
+
|
|
89
124
|
export class CursorSdkRunner implements AgentRunner {
|
|
90
|
-
private readonly agents = new Map<string,
|
|
125
|
+
private readonly agents = new Map<string, CachedAgentHandle>();
|
|
91
126
|
private readonly stores = new Map<string, Promise<LocalAgentStore>>();
|
|
92
127
|
private readonly prewarmReleases: Array<() => Promise<void>> = [];
|
|
93
128
|
|
|
94
129
|
constructor(private readonly options: CursorSdkRunnerOptions = {}) {}
|
|
95
130
|
|
|
96
131
|
async runTurn(request: RunnerTurnRequest): Promise<TurnOutcome> {
|
|
132
|
+
let sawUpdate = false;
|
|
133
|
+
const tracked: RunnerTurnRequest = {
|
|
134
|
+
...request,
|
|
135
|
+
onUpdate: (update) => {
|
|
136
|
+
sawUpdate = true;
|
|
137
|
+
return request.onUpdate(update);
|
|
138
|
+
},
|
|
139
|
+
};
|
|
140
|
+
const outcome = await this.runTurnAttempt(tracked);
|
|
141
|
+
if (
|
|
142
|
+
outcome.status !== "error" ||
|
|
143
|
+
!isAuthErrorMessage(outcome.errorMessage) ||
|
|
144
|
+
sawUpdate ||
|
|
145
|
+
request.isFirstTurn ||
|
|
146
|
+
request.signal?.aborted === true
|
|
147
|
+
) {
|
|
148
|
+
return outcome;
|
|
149
|
+
}
|
|
150
|
+
// The turn died on an authentication failure before producing any output
|
|
151
|
+
// — the signature of a handle whose exchanged access token expired (the
|
|
152
|
+
// failed attempt already evicted it). Retrying once on a fresh handle is
|
|
153
|
+
// safe here because nothing streamed and no tool ran. First turns are
|
|
154
|
+
// excluded: their token was exchanged moments ago, so the credential
|
|
155
|
+
// itself is the problem and a retry cannot succeed.
|
|
156
|
+
this.log(
|
|
157
|
+
`[agentkit] session ${request.sessionId}: retrying the turn on a fresh SDK agent handle after an authentication failure`
|
|
158
|
+
);
|
|
159
|
+
try {
|
|
160
|
+
return await this.runTurnAttempt(tracked);
|
|
161
|
+
} catch {
|
|
162
|
+
// The retry was best effort; report the original failure.
|
|
163
|
+
return outcome;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
private async runTurnAttempt(
|
|
168
|
+
request: RunnerTurnRequest
|
|
169
|
+
): Promise<TurnOutcome> {
|
|
170
|
+
const agentPromise = this.getAgent(request);
|
|
97
171
|
try {
|
|
98
|
-
const agent = await
|
|
172
|
+
const agent = await agentPromise;
|
|
99
173
|
const run = await agent.send(request.prompt, {
|
|
100
174
|
onDelta: async ({ update }) => {
|
|
101
175
|
try {
|
|
@@ -141,14 +215,24 @@ export class CursorSdkRunner implements AgentRunner {
|
|
|
141
215
|
}
|
|
142
216
|
try {
|
|
143
217
|
const result = await run.wait();
|
|
144
|
-
|
|
218
|
+
const outcome = toTurnOutcome(result);
|
|
219
|
+
if (outcome.status === "error") {
|
|
220
|
+
// An error result usually means the handle's transport is poisoned
|
|
221
|
+
// — most often a cached access token that aged past its 60-minute
|
|
222
|
+
// lifetime and gets replayed on every request (stream failures
|
|
223
|
+
// bypass the transport's 401 retry). Retire the handle so the next
|
|
224
|
+
// attempt resumes the conversation from the store on a fresh
|
|
225
|
+
// transport instead of failing every turn until a restart.
|
|
226
|
+
this.evictAgent(request.sessionId, agentPromise);
|
|
227
|
+
}
|
|
228
|
+
return outcome;
|
|
145
229
|
} finally {
|
|
146
230
|
signal?.removeEventListener("abort", onAbort);
|
|
147
231
|
}
|
|
148
232
|
} catch (error) {
|
|
149
233
|
// Drop the cached agent so a dead Connect/HTTP2 session cannot poison
|
|
150
234
|
// the next turn (terminal/shell overflow often kills the transport).
|
|
151
|
-
this.
|
|
235
|
+
this.evictAgent(request.sessionId, agentPromise);
|
|
152
236
|
throw error;
|
|
153
237
|
}
|
|
154
238
|
}
|
|
@@ -178,7 +262,9 @@ export class CursorSdkRunner implements AgentRunner {
|
|
|
178
262
|
async dispose(): Promise<void> {
|
|
179
263
|
const releases = this.prewarmReleases.splice(0);
|
|
180
264
|
await Promise.allSettled(releases.map((release) => release()));
|
|
181
|
-
const agents = await Promise.allSettled(
|
|
265
|
+
const agents = await Promise.allSettled(
|
|
266
|
+
[...this.agents.values()].map((handle) => handle.agent)
|
|
267
|
+
);
|
|
182
268
|
this.agents.clear();
|
|
183
269
|
for (const settled of agents) {
|
|
184
270
|
if (settled.status === "fulfilled") {
|
|
@@ -188,17 +274,49 @@ export class CursorSdkRunner implements AgentRunner {
|
|
|
188
274
|
}
|
|
189
275
|
|
|
190
276
|
private getAgent(request: RunnerTurnRequest): Promise<SDKAgent> {
|
|
191
|
-
|
|
192
|
-
if (
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
}
|
|
197
|
-
this
|
|
277
|
+
const cached = this.agents.get(request.sessionId);
|
|
278
|
+
if (cached !== undefined) {
|
|
279
|
+
const ageMs = Date.now() - cached.openedAtMs;
|
|
280
|
+
if (ageMs < MAX_AGENT_HANDLE_AGE_MS) {
|
|
281
|
+
return cached.agent;
|
|
282
|
+
}
|
|
283
|
+
// Past this age the handle's exchanged access token could expire
|
|
284
|
+
// mid-turn. Retire it and reopen below on a fresh transport.
|
|
285
|
+
this.log(
|
|
286
|
+
`[agentkit] session ${request.sessionId}: recycling the SDK agent handle after ${Math.round(ageMs / 60_000)} min so the turn runs on a fresh access token`
|
|
287
|
+
);
|
|
288
|
+
this.evictAgent(request.sessionId, cached.agent);
|
|
198
289
|
}
|
|
290
|
+
const agentPromise = this.openAgent(request).catch((error) => {
|
|
291
|
+
// Nothing opened, so there is no handle to close — just free the slot.
|
|
292
|
+
this.agents.delete(request.sessionId);
|
|
293
|
+
throw error;
|
|
294
|
+
});
|
|
295
|
+
this.agents.set(request.sessionId, {
|
|
296
|
+
agent: agentPromise,
|
|
297
|
+
openedAtMs: Date.now(),
|
|
298
|
+
});
|
|
199
299
|
return agentPromise;
|
|
200
300
|
}
|
|
201
301
|
|
|
302
|
+
/**
|
|
303
|
+
* Drop a cached handle and close it best-effort to release its transport
|
|
304
|
+
* and executor lease. Identity-checked so a turn that lost a race with a
|
|
305
|
+
* newer open cannot evict the replacement handle.
|
|
306
|
+
*/
|
|
307
|
+
private evictAgent(sessionId: string, agent: Promise<SDKAgent>): void {
|
|
308
|
+
const cached = this.agents.get(sessionId);
|
|
309
|
+
if (cached === undefined || cached.agent !== agent) {
|
|
310
|
+
return;
|
|
311
|
+
}
|
|
312
|
+
this.agents.delete(sessionId);
|
|
313
|
+
void cached.agent.then((sdkAgent) => sdkAgent.close()).catch(() => {});
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
private log(line: string): void {
|
|
317
|
+
(this.options.logger ?? (() => {}))(line);
|
|
318
|
+
}
|
|
319
|
+
|
|
202
320
|
private requireApiKey(): string {
|
|
203
321
|
const apiKey = this.options.apiKey ?? process.env.CURSOR_API_KEY;
|
|
204
322
|
if (apiKey === undefined || apiKey.trim() === "") {
|
|
@@ -274,7 +392,7 @@ export class CursorSdkRunner implements AgentRunner {
|
|
|
274
392
|
// conversation under the same id beats failing this thread's turns
|
|
275
393
|
// forever ("Agent … not found" on every follow-up). The channel's
|
|
276
394
|
// warm-turn prompt context re-hydrates the thread history.
|
|
277
|
-
|
|
395
|
+
this.log(
|
|
278
396
|
`[agentkit] no stored conversation for ${agentId} on this host; starting a fresh one`
|
|
279
397
|
);
|
|
280
398
|
return Agent.create({ ...options, agentId });
|
package/src/internal/server.ts
CHANGED
|
@@ -421,6 +421,8 @@ export async function startServer(
|
|
|
421
421
|
cancel: (id, reason) => reminderRunner.cancel(id, reason),
|
|
422
422
|
cancelForContinuation: (token, reason) =>
|
|
423
423
|
reminderRunner.cancelForContinuation(token, reason),
|
|
424
|
+
rekeyContinuation: (channelId, oldToken, newToken) =>
|
|
425
|
+
reminderRunner.rekeyContinuation(channelId, oldToken, newToken),
|
|
424
426
|
dispatch: (id) => reminderRunner.dispatch(id),
|
|
425
427
|
});
|
|
426
428
|
engine.setEvals({
|
|
@@ -2148,10 +2148,24 @@ export class SessionEngine {
|
|
|
2148
2148
|
sessionId: string,
|
|
2149
2149
|
token: string | null
|
|
2150
2150
|
): Promise<void> {
|
|
2151
|
+
const previous = await this.sessions.get(sessionId);
|
|
2151
2152
|
await this.updateRecord(sessionId, (current) => ({
|
|
2152
2153
|
...current,
|
|
2153
2154
|
continuationKey: token,
|
|
2154
2155
|
}));
|
|
2156
|
+
// Keep armed reminders addressed at the conversation across rotation
|
|
2157
|
+
// (the built-in HTTP channel rotates after every follow-up).
|
|
2158
|
+
if (
|
|
2159
|
+
previous?.continuationKey != null &&
|
|
2160
|
+
token !== null &&
|
|
2161
|
+
token !== previous.continuationKey
|
|
2162
|
+
) {
|
|
2163
|
+
await this.reminderApi?.rekeyContinuation(
|
|
2164
|
+
previous.channelId,
|
|
2165
|
+
previous.continuationKey,
|
|
2166
|
+
token
|
|
2167
|
+
);
|
|
2168
|
+
}
|
|
2155
2169
|
}
|
|
2156
2170
|
|
|
2157
2171
|
isTurnRunning(sessionId: string): boolean {
|
|
@@ -9,9 +9,10 @@
|
|
|
9
9
|
* The endpoints are gated on the `agent_serve_slack_provisioning` Statsig
|
|
10
10
|
* gate and 404 when it is off — the error mapping says so instead of
|
|
11
11
|
* "not found". Expected provisioning failures carry a stable JSON `code`
|
|
12
|
-
* (`not_connected`, `insufficient_scopes`, `
|
|
13
|
-
* `app_cap_reached`, `ratelimited`, `invalid_app_id`, …)
|
|
14
|
-
* through on {@link SlackProvisionApiError.code} so the CLI
|
|
12
|
+
* (`not_connected`, `insufficient_scopes`, `manager_reauth_required`,
|
|
13
|
+
* `app_conflict`, `app_cap_reached`, `ratelimited`, `invalid_app_id`, …)
|
|
14
|
+
* which flows through on {@link SlackProvisionApiError.code} so the CLI
|
|
15
|
+
* can branch.
|
|
15
16
|
*/
|
|
16
17
|
|
|
17
18
|
import { z } from "zod";
|
|
@@ -21,6 +22,8 @@ export type SlackAppEnv = "dev" | "prod";
|
|
|
21
22
|
/** One manager-connected Slack workspace from `GET /status`. */
|
|
22
23
|
export interface SlackConnectedWorkspace {
|
|
23
24
|
slackTeamId: string;
|
|
25
|
+
/** Workspace name; absent on older backends, null on pre-existing rows. */
|
|
26
|
+
slackTeamName?: string | null;
|
|
24
27
|
slackUserId: string;
|
|
25
28
|
connectedAt: string;
|
|
26
29
|
}
|
|
@@ -113,6 +116,7 @@ const statusResponseSchema = z
|
|
|
113
116
|
z
|
|
114
117
|
.object({
|
|
115
118
|
slackTeamId: z.string(),
|
|
119
|
+
slackTeamName: z.string().nullish(),
|
|
116
120
|
slackUserId: z.string(),
|
|
117
121
|
connectedAt: z.string(),
|
|
118
122
|
})
|
package/src/types.ts
CHANGED
|
@@ -198,6 +198,29 @@ export interface AgentConfig {
|
|
|
198
198
|
* Engine-wide turn admission limits. See {@link AgentConcurrencyOptions}.
|
|
199
199
|
*/
|
|
200
200
|
concurrency?: AgentConcurrencyOptions;
|
|
201
|
+
/**
|
|
202
|
+
* Framework-provided model-facing tools, opted in per capability. See
|
|
203
|
+
* {@link BuiltinToolsConfig}.
|
|
204
|
+
*/
|
|
205
|
+
builtinTools?: BuiltinToolsConfig;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* Built-in tools on {@link AgentConfig.builtinTools}. Each enabled
|
|
210
|
+
* capability materializes as ordinary server tools at discovery time, so
|
|
211
|
+
* turns, direct calls, `info`, and the playground treat them like authored
|
|
212
|
+
* tools. Authored tools with the same name win (with a warning), and none
|
|
213
|
+
* of them run on cloud turns (server tools are local-runtime only).
|
|
214
|
+
*/
|
|
215
|
+
export interface BuiltinToolsConfig {
|
|
216
|
+
/**
|
|
217
|
+
* Reminder tools bound to the current conversation, over
|
|
218
|
+
* {@link HostContext.reminders}: `reminders_create`, `reminders_list`,
|
|
219
|
+
* and `reminders_cancel` (the name the framework's reminder fire prompt
|
|
220
|
+
* tells the model to call when a stop condition is met). Sessions
|
|
221
|
+
* without a continuation key cannot arm reminders.
|
|
222
|
+
*/
|
|
223
|
+
reminders?: boolean;
|
|
201
224
|
}
|
|
202
225
|
|
|
203
226
|
/**
|
|
@@ -1722,6 +1745,16 @@ export interface ReminderHostApi {
|
|
|
1722
1745
|
continuationToken: string,
|
|
1723
1746
|
reason: string
|
|
1724
1747
|
): Promise<number>;
|
|
1748
|
+
/**
|
|
1749
|
+
* Re-key armed reminders after a channel rotates a session's continuation
|
|
1750
|
+
* token, so earlier reminders keep waking the conversation. The engine
|
|
1751
|
+
* calls this from `setContinuationToken`; channels rarely need to.
|
|
1752
|
+
*/
|
|
1753
|
+
rekeyContinuation(
|
|
1754
|
+
channelId: string,
|
|
1755
|
+
oldToken: string,
|
|
1756
|
+
newToken: string
|
|
1757
|
+
): Promise<number>;
|
|
1725
1758
|
/**
|
|
1726
1759
|
* Fire immediately (dev / hillclimb).
|
|
1727
1760
|
* `outcome` is `"noop"` when already firing or not armed.
|