@economic/agents 2.13.0 → 2.14.0
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 +11 -0
- package/dist/index.d.mts +64 -42
- package/dist/index.mjs +134 -3
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -421,6 +421,7 @@ import { z } from "zod";
|
|
|
421
421
|
|
|
422
422
|
export const weatherSkill = skill({
|
|
423
423
|
name: "weather",
|
|
424
|
+
command: "weather",
|
|
424
425
|
description: "Look up current weather and forecasts. Use for any weather question.",
|
|
425
426
|
instructions: `
|
|
426
427
|
# Weather
|
|
@@ -445,6 +446,16 @@ Use this skill whenever the user asks about current conditions or a forecast.
|
|
|
445
446
|
|
|
446
447
|
Return skills from `getSkills()`. Add `authorize(ctx)` to gate a skill (and its tools). Denied skills are hidden from the catalog and `activate_skill` by default. Set `onUnauthorized` to a reason string, or a function that returns one, to expose a denied skill with user-facing guidance. A function can return `undefined` to keep it hidden. `skill()` throws if `description` or `instructions` is missing.
|
|
447
448
|
|
|
449
|
+
Set `command` to make a code-defined skill directly invocable from chat. For example,
|
|
450
|
+
`/weather in Copenhagen` loads the weather instructions and enables its tools before the
|
|
451
|
+
first model step; the model still interprets `in Copenhagen` and chooses the appropriate
|
|
452
|
+
tool. Commands use lower-case letters, numbers, and hyphens, without the leading `/`.
|
|
453
|
+
|
|
454
|
+
`ChatAgent` also exposes an authenticated `GET getInvocableSkills` action for command
|
|
455
|
+
pickers. It returns the commands available to the current user as
|
|
456
|
+
`{ command, name, description }[]`. The existing skill `description` is used for both the
|
|
457
|
+
model catalog and the human-facing picker.
|
|
458
|
+
|
|
448
459
|
### Native Agent Skills
|
|
449
460
|
|
|
450
461
|
Native Agent Skills are folders containing a `SKILL.md` file, with optional references and scripts:
|
package/dist/index.d.mts
CHANGED
|
@@ -153,6 +153,11 @@ type AnalyticsEventPayload = {
|
|
|
153
153
|
durationMs: number;
|
|
154
154
|
inputSize: number;
|
|
155
155
|
outputSize: number;
|
|
156
|
+
} | {
|
|
157
|
+
type: "skill.invoked";
|
|
158
|
+
skillName: string;
|
|
159
|
+
command: string;
|
|
160
|
+
source: "slash-command";
|
|
156
161
|
} | {
|
|
157
162
|
type: "feedback.submitted";
|
|
158
163
|
messageId: string;
|
|
@@ -207,6 +212,7 @@ declare class Analytics {
|
|
|
207
212
|
promptReceived(messages: readonly ModelMessage[], continuation: boolean): void;
|
|
208
213
|
turnCompleted(requestId: string, status: string, continuation: boolean, response: unknown): void;
|
|
209
214
|
feedbackSubmitted(messageId: string, rating: 1 | -1 | 0): void;
|
|
215
|
+
skillInvoked(skillName: string, command: string): void;
|
|
210
216
|
event(payload: AnalyticsEventPayload | (() => AnalyticsEventPayload)): void;
|
|
211
217
|
}
|
|
212
218
|
//#endregion
|
|
@@ -432,12 +438,69 @@ type MessageFeedback = {
|
|
|
432
438
|
updated_at: number;
|
|
433
439
|
};
|
|
434
440
|
//#endregion
|
|
441
|
+
//#region src/server/util/actions.d.ts
|
|
442
|
+
/** Tool execution options plus the additional context supplied by native Think actions. */
|
|
443
|
+
type ActionContext<Context extends Record<string, unknown> = Record<string, unknown>> = Omit<ToolExecutionOptions, "experimental_context"> & ActionContext$1 & {
|
|
444
|
+
experimental_context: Context; /** The action's resolved domain key, or its tool-call fallback when none was declared. */
|
|
445
|
+
idempotencyKey: string;
|
|
446
|
+
};
|
|
447
|
+
type Action<Context extends Record<string, unknown> = Record<string, unknown>, Input = any, Output = any> = Omit<ActionConfig<FlexibleSchema<Input>, Output>, "approval" | "execute" | "idempotencyKey" | "inputSchema" | "permissions"> & {
|
|
448
|
+
description: string;
|
|
449
|
+
inputSchema: FlexibleSchema<Input>;
|
|
450
|
+
approval?: ActionApprovalPolicy<Input>;
|
|
451
|
+
idempotencyKey?: ActionIdempotencyKey<Input>;
|
|
452
|
+
permissions?: ActionPermissionSpec<Input>;
|
|
453
|
+
authorize?: (ctx?: Context) => boolean;
|
|
454
|
+
onUnauthorized?: UnauthorizedPolicy<Context>;
|
|
455
|
+
execute(input: Input, ctx: ActionContext<Context>): Promise<Output> | Output;
|
|
456
|
+
};
|
|
457
|
+
type RegisteredAction<Context extends Record<string, unknown> = Record<string, unknown>, InputSchema extends FlexibleSchema = FlexibleSchema, Output = unknown> = Action$1<InputSchema, Output> & {
|
|
458
|
+
authorize?: (ctx?: Context) => boolean;
|
|
459
|
+
onUnauthorized?: UnauthorizedPolicy<Context>;
|
|
460
|
+
};
|
|
461
|
+
/** A native Think action with the SDK's standard authorization policy. */
|
|
462
|
+
declare function action<Context extends Record<string, unknown> = Record<string, unknown>, Input = any, Output = any>(definition: Action<Context, Input, Output>): RegisteredAction<Context, FlexibleSchema<Input>, Output>;
|
|
463
|
+
//#endregion
|
|
464
|
+
//#region src/server/util/skills.d.ts
|
|
465
|
+
interface Skill<Context extends Record<string, unknown> = Record<string, unknown>> {
|
|
466
|
+
name: string;
|
|
467
|
+
description: string;
|
|
468
|
+
instructions: string;
|
|
469
|
+
/** Enables direct invocation from chat with `/command`. */
|
|
470
|
+
command?: string;
|
|
471
|
+
tools?: Record<string, Tool<Context>>;
|
|
472
|
+
actions?: Record<string, RegisteredAction<Context, any, any>>;
|
|
473
|
+
authorize?: (ctx?: Context) => boolean;
|
|
474
|
+
onUnauthorized?: UnauthorizedPolicy<Context>;
|
|
475
|
+
}
|
|
476
|
+
interface SkillSource<Context extends Record<string, unknown> = Record<string, unknown>> extends SkillSource$1 {
|
|
477
|
+
command?: string;
|
|
478
|
+
tools?: Record<string, Tool<Context>>;
|
|
479
|
+
actions?: Record<string, RegisteredAction<Context, any, any>>;
|
|
480
|
+
authorize?: (ctx?: Context | undefined) => boolean;
|
|
481
|
+
onUnauthorized?: UnauthorizedPolicy<Context>;
|
|
482
|
+
}
|
|
483
|
+
declare function skill<Context extends Record<string, unknown> = Record<string, unknown>>(definition: Skill<Context>): SkillSource<Context>;
|
|
484
|
+
//#endregion
|
|
485
|
+
//#region src/server/util/skillCommands.d.ts
|
|
486
|
+
interface InvocableSkill {
|
|
487
|
+
/** Slash command without the leading `/`. */
|
|
488
|
+
command: string;
|
|
489
|
+
/** Name of the skill the command activates. */
|
|
490
|
+
name: string;
|
|
491
|
+
/** Human- and model-readable summary from the skill definition. */
|
|
492
|
+
description: string;
|
|
493
|
+
}
|
|
494
|
+
//#endregion
|
|
435
495
|
//#region src/server/agents/ChatAgent.d.ts
|
|
436
496
|
declare abstract class ChatAgent<RequestContext extends Record<string, unknown> = Record<string, unknown>, UserContext extends Record<string, unknown> = Record<string, unknown>, State = unknown> extends Agent<RequestContext, UserContext, State> {
|
|
437
497
|
protected agentType: AgentConnectionType;
|
|
438
498
|
onStart(): Promise<void>;
|
|
439
499
|
configureSession(session: Session): Session;
|
|
440
500
|
beforeTurn(ctx: TurnContext): Promise<void | TurnConfig>;
|
|
501
|
+
private getSlashCommandSkill;
|
|
502
|
+
private invokeSkill;
|
|
503
|
+
protected getInvocableSkills(userContext?: UserContext | undefined, requestContext?: RequestContext): Promise<InvocableSkill[]>;
|
|
441
504
|
onChatResponse(result: ChatResponseResult): Promise<void>;
|
|
442
505
|
onRequest(request: Request): Promise<Response>;
|
|
443
506
|
/**
|
|
@@ -512,51 +575,10 @@ declare abstract class Assistant<State = unknown> extends Agent$1<Cloudflare.Env
|
|
|
512
575
|
observability?: Observability;
|
|
513
576
|
}
|
|
514
577
|
//#endregion
|
|
515
|
-
//#region src/server/util/actions.d.ts
|
|
516
|
-
/** Tool execution options plus the additional context supplied by native Think actions. */
|
|
517
|
-
type ActionContext<Context extends Record<string, unknown> = Record<string, unknown>> = Omit<ToolExecutionOptions, "experimental_context"> & ActionContext$1 & {
|
|
518
|
-
experimental_context: Context; /** The action's resolved domain key, or its tool-call fallback when none was declared. */
|
|
519
|
-
idempotencyKey: string;
|
|
520
|
-
};
|
|
521
|
-
type Action<Context extends Record<string, unknown> = Record<string, unknown>, Input = any, Output = any> = Omit<ActionConfig<FlexibleSchema<Input>, Output>, "approval" | "execute" | "idempotencyKey" | "inputSchema" | "permissions"> & {
|
|
522
|
-
description: string;
|
|
523
|
-
inputSchema: FlexibleSchema<Input>;
|
|
524
|
-
approval?: ActionApprovalPolicy<Input>;
|
|
525
|
-
idempotencyKey?: ActionIdempotencyKey<Input>;
|
|
526
|
-
permissions?: ActionPermissionSpec<Input>;
|
|
527
|
-
authorize?: (ctx?: Context) => boolean;
|
|
528
|
-
onUnauthorized?: UnauthorizedPolicy<Context>;
|
|
529
|
-
execute(input: Input, ctx: ActionContext<Context>): Promise<Output> | Output;
|
|
530
|
-
};
|
|
531
|
-
type RegisteredAction<Context extends Record<string, unknown> = Record<string, unknown>, InputSchema extends FlexibleSchema = FlexibleSchema, Output = unknown> = Action$1<InputSchema, Output> & {
|
|
532
|
-
authorize?: (ctx?: Context) => boolean;
|
|
533
|
-
onUnauthorized?: UnauthorizedPolicy<Context>;
|
|
534
|
-
};
|
|
535
|
-
/** A native Think action with the SDK's standard authorization policy. */
|
|
536
|
-
declare function action<Context extends Record<string, unknown> = Record<string, unknown>, Input = any, Output = any>(definition: Action<Context, Input, Output>): RegisteredAction<Context, FlexibleSchema<Input>, Output>;
|
|
537
|
-
//#endregion
|
|
538
|
-
//#region src/server/util/skills.d.ts
|
|
539
|
-
interface Skill<Context extends Record<string, unknown> = Record<string, unknown>> {
|
|
540
|
-
name: string;
|
|
541
|
-
description: string;
|
|
542
|
-
instructions: string;
|
|
543
|
-
tools?: Record<string, Tool<Context>>;
|
|
544
|
-
actions?: Record<string, RegisteredAction<Context, any, any>>;
|
|
545
|
-
authorize?: (ctx?: Context) => boolean;
|
|
546
|
-
onUnauthorized?: UnauthorizedPolicy<Context>;
|
|
547
|
-
}
|
|
548
|
-
interface SkillSource<Context extends Record<string, unknown> = Record<string, unknown>> extends SkillSource$1 {
|
|
549
|
-
tools?: Record<string, Tool<Context>>;
|
|
550
|
-
actions?: Record<string, RegisteredAction<Context, any, any>>;
|
|
551
|
-
authorize?: (ctx?: Context | undefined) => boolean;
|
|
552
|
-
onUnauthorized?: UnauthorizedPolicy<Context>;
|
|
553
|
-
}
|
|
554
|
-
declare function skill<Context extends Record<string, unknown> = Record<string, unknown>>(definition: Skill<Context>): SkillSource<Context>;
|
|
555
|
-
//#endregion
|
|
556
578
|
//#region src/server/route-agent-request.d.ts
|
|
557
579
|
declare function routeAgentRequest<Env>(request: Request, env: Env, options?: AgentOptions<Env>): Promise<Response | null>;
|
|
558
580
|
//#endregion
|
|
559
581
|
//#region src/server/index.d.ts
|
|
560
582
|
declare function getCurrentToolContext(): any;
|
|
561
583
|
//#endregion
|
|
562
|
-
export { type Action, type ActionContext, Agent, type AgentConnectionStatus, type AgentConnectionType, type AgentEnv, type AnalyticsAttribute, type AnalyticsAttributes, type AnalyticsEvent, type AnalyticsEventPayload, type AnalyticsHandler, type AnalyticsUsage, Assistant, ChatAgent, type ExchangedToken, type JwtAuthConfig, type RegisteredAction, type Skill, type SkillSource, type TokenExchangeConfig, type TokenExchangeResult, type Tool, type ToolContext, type ToolSet, type TurnSnapshot, type UnauthorizedPolicy, type UnauthorizedToolPolicy, action, createAnalyticsEngineHandler, createAnalyticsEvent, createJwtAuthConfig, dispatchAnalyticsEvent, exchangeToken, getCurrentToolContext, routeAgentRequest, skill, tool };
|
|
584
|
+
export { type Action, type ActionContext, Agent, type AgentConnectionStatus, type AgentConnectionType, type AgentEnv, type AnalyticsAttribute, type AnalyticsAttributes, type AnalyticsEvent, type AnalyticsEventPayload, type AnalyticsHandler, type AnalyticsUsage, Assistant, ChatAgent, type ExchangedToken, type InvocableSkill, type JwtAuthConfig, type RegisteredAction, type Skill, type SkillSource, type TokenExchangeConfig, type TokenExchangeResult, type Tool, type ToolContext, type ToolSet, type TurnSnapshot, type UnauthorizedPolicy, type UnauthorizedToolPolicy, action, createAnalyticsEngineHandler, createAnalyticsEvent, createJwtAuthConfig, dispatchAnalyticsEvent, exchangeToken, getCurrentToolContext, routeAgentRequest, skill, tool };
|
package/dist/index.mjs
CHANGED
|
@@ -905,6 +905,19 @@ function toAnalyticsEnginePoints(event) {
|
|
|
905
905
|
0
|
|
906
906
|
]
|
|
907
907
|
}));
|
|
908
|
+
case "skill.invoked": return [{
|
|
909
|
+
indexes,
|
|
910
|
+
blobs: [
|
|
911
|
+
"skill_invoked",
|
|
912
|
+
event.agentName,
|
|
913
|
+
event.durableObjectName,
|
|
914
|
+
event.skillName,
|
|
915
|
+
event.command,
|
|
916
|
+
event.source,
|
|
917
|
+
...common
|
|
918
|
+
],
|
|
919
|
+
doubles: [1]
|
|
920
|
+
}];
|
|
908
921
|
case "feedback.submitted": return [{
|
|
909
922
|
indexes,
|
|
910
923
|
blobs: [
|
|
@@ -998,6 +1011,14 @@ var Analytics = class {
|
|
|
998
1011
|
rating
|
|
999
1012
|
});
|
|
1000
1013
|
}
|
|
1014
|
+
skillInvoked(skillName, command) {
|
|
1015
|
+
this.emit({
|
|
1016
|
+
type: "skill.invoked",
|
|
1017
|
+
skillName,
|
|
1018
|
+
command,
|
|
1019
|
+
source: "slash-command"
|
|
1020
|
+
});
|
|
1021
|
+
}
|
|
1001
1022
|
event(payload) {
|
|
1002
1023
|
this.emit(payload);
|
|
1003
1024
|
}
|
|
@@ -1161,7 +1182,6 @@ var Agent = class extends Think {
|
|
|
1161
1182
|
const { tools, activeTools } = await this._prepareTools(ctx.tools, activeSkillName, true);
|
|
1162
1183
|
const baseSystem = await this.session.refreshSystemPrompt();
|
|
1163
1184
|
this._turn.baseSystem = [baseSystem, this._turn.skillsSystemBlock].filter(Boolean).join("\n\n");
|
|
1164
|
-
console.log(this._turn.baseSystem, "\n\n// end system prompt\n\n");
|
|
1165
1185
|
return {
|
|
1166
1186
|
system: this._turn.baseSystem,
|
|
1167
1187
|
model: this.getModel(this._turn.context),
|
|
@@ -2338,6 +2358,38 @@ var Assistant = class extends Agent$1 {
|
|
|
2338
2358
|
agentClass: this.constructor.name
|
|
2339
2359
|
}) });
|
|
2340
2360
|
};
|
|
2361
|
+
//#endregion
|
|
2362
|
+
//#region src/server/util/skillCommands.ts
|
|
2363
|
+
async function listInvocableSkills(sources) {
|
|
2364
|
+
const commands = /* @__PURE__ */ new Set();
|
|
2365
|
+
const skills = [];
|
|
2366
|
+
for (const source of sources) {
|
|
2367
|
+
if (!source.command) continue;
|
|
2368
|
+
if (commands.has(source.command)) throw new Error(`Duplicate skill command "/${source.command}"`);
|
|
2369
|
+
const descriptor = (await source.list()).find((skill) => skill.name === source.id);
|
|
2370
|
+
if (!descriptor) continue;
|
|
2371
|
+
commands.add(source.command);
|
|
2372
|
+
skills.push({
|
|
2373
|
+
command: source.command,
|
|
2374
|
+
name: descriptor.name,
|
|
2375
|
+
description: descriptor.description
|
|
2376
|
+
});
|
|
2377
|
+
}
|
|
2378
|
+
return skills;
|
|
2379
|
+
}
|
|
2380
|
+
function parseSkillCommand(messages, skills) {
|
|
2381
|
+
const message = messages.findLast((candidate) => candidate.role === "user");
|
|
2382
|
+
if (!message) return;
|
|
2383
|
+
const text = getMessageText(message);
|
|
2384
|
+
if (!text?.startsWith("/")) return;
|
|
2385
|
+
const match = /^\/([^\s]+)/.exec(text);
|
|
2386
|
+
if (!match) return;
|
|
2387
|
+
return skills.find((skill) => skill.command === match[1]);
|
|
2388
|
+
}
|
|
2389
|
+
function getMessageText(message) {
|
|
2390
|
+
if (typeof message.content === "string") return message.content;
|
|
2391
|
+
return message.content.filter((part) => part.type === "text").map((part) => part.text).join("") || void 0;
|
|
2392
|
+
}
|
|
2341
2393
|
const COMPACTION_MAX_OUTPUT_TOKENS = 2e3;
|
|
2342
2394
|
const createCompactFn = (model) => createCompactFunction({
|
|
2343
2395
|
protectHead: 2,
|
|
@@ -2675,7 +2727,22 @@ var ChatAgent = class extends Agent {
|
|
|
2675
2727
|
async beforeTurn(ctx) {
|
|
2676
2728
|
const parent = await this.getParentAgent();
|
|
2677
2729
|
if (parent?.registerChat) await parent.registerChat(this.name);
|
|
2678
|
-
const
|
|
2730
|
+
const slashCommandSkill = await this.getSlashCommandSkill(ctx);
|
|
2731
|
+
let skillInvocation;
|
|
2732
|
+
if (slashCommandSkill) skillInvocation = await this.invokeSkill(ctx, slashCommandSkill);
|
|
2733
|
+
const turnContext = skillInvocation ? {
|
|
2734
|
+
...ctx,
|
|
2735
|
+
messages: [...ctx.messages, ...skillInvocation.messages]
|
|
2736
|
+
} : ctx;
|
|
2737
|
+
let config = await super.beforeTurn(turnContext) ?? {};
|
|
2738
|
+
if (skillInvocation) {
|
|
2739
|
+
const transforms = config.experimental_transform ? Array.isArray(config.experimental_transform) ? config.experimental_transform : [config.experimental_transform] : [];
|
|
2740
|
+
config = {
|
|
2741
|
+
...config,
|
|
2742
|
+
activeTools: config.activeTools?.filter((name) => name !== "activate_skill"),
|
|
2743
|
+
experimental_transform: [skillInvocation.transform, ...transforms]
|
|
2744
|
+
};
|
|
2745
|
+
}
|
|
2679
2746
|
try {
|
|
2680
2747
|
const prepared = await prepareModelHistory(this.messages, getModelCompaction(this.sql.bind(this)), createCompactFn(config.model ?? ctx.model), config.system ?? ctx.system);
|
|
2681
2748
|
if (prepared.stateChanged) if (prepared.state) setModelCompaction(this.sql.bind(this), prepared.state);
|
|
@@ -2691,7 +2758,7 @@ var ChatAgent = class extends Agent {
|
|
|
2691
2758
|
});
|
|
2692
2759
|
return {
|
|
2693
2760
|
...config,
|
|
2694
|
-
messages: this.pruneTurnMessages(modelMessages)
|
|
2761
|
+
messages: this.pruneTurnMessages([...modelMessages, ...skillInvocation?.messages ?? []])
|
|
2695
2762
|
};
|
|
2696
2763
|
}
|
|
2697
2764
|
} catch (error) {
|
|
@@ -2699,6 +2766,67 @@ var ChatAgent = class extends Agent {
|
|
|
2699
2766
|
}
|
|
2700
2767
|
return config;
|
|
2701
2768
|
}
|
|
2769
|
+
async getSlashCommandSkill(context) {
|
|
2770
|
+
if (context.continuation) return;
|
|
2771
|
+
const connectionState = getCurrentAgent()?.connection?.state;
|
|
2772
|
+
const invocableSkills = await this.getInvocableSkills(connectionState?.userContext ?? this.userContext, context.body);
|
|
2773
|
+
return parseSkillCommand(context.messages, invocableSkills);
|
|
2774
|
+
}
|
|
2775
|
+
async invokeSkill(context, skill) {
|
|
2776
|
+
const activateSkill = context.tools.activate_skill;
|
|
2777
|
+
if (!activateSkill?.execute) return;
|
|
2778
|
+
const input = { name: skill.name };
|
|
2779
|
+
const toolCallId = crypto.randomUUID();
|
|
2780
|
+
const output = await activateSkill.execute(input, {
|
|
2781
|
+
toolCallId,
|
|
2782
|
+
messages: context.messages
|
|
2783
|
+
});
|
|
2784
|
+
if (typeof output !== "string") throw new Error("activate_skill returned an invalid result");
|
|
2785
|
+
this.analytics.skillInvoked(skill.name, skill.command);
|
|
2786
|
+
const messages = await convertToModelMessages([{
|
|
2787
|
+
id: crypto.randomUUID(),
|
|
2788
|
+
role: "assistant",
|
|
2789
|
+
parts: [{
|
|
2790
|
+
type: "tool-activate_skill",
|
|
2791
|
+
toolCallId,
|
|
2792
|
+
state: "output-available",
|
|
2793
|
+
input,
|
|
2794
|
+
output
|
|
2795
|
+
}]
|
|
2796
|
+
}], { tools: context.tools });
|
|
2797
|
+
const transform = () => {
|
|
2798
|
+
let emitted = false;
|
|
2799
|
+
return new TransformStream({ transform(chunk, controller) {
|
|
2800
|
+
controller.enqueue(chunk);
|
|
2801
|
+
if (emitted || chunk.type !== "start-step") return;
|
|
2802
|
+
emitted = true;
|
|
2803
|
+
controller.enqueue({
|
|
2804
|
+
type: "tool-call",
|
|
2805
|
+
toolCallId,
|
|
2806
|
+
toolName: "activate_skill",
|
|
2807
|
+
input
|
|
2808
|
+
});
|
|
2809
|
+
controller.enqueue({
|
|
2810
|
+
type: "tool-result",
|
|
2811
|
+
toolCallId,
|
|
2812
|
+
toolName: "activate_skill",
|
|
2813
|
+
input,
|
|
2814
|
+
output
|
|
2815
|
+
});
|
|
2816
|
+
} });
|
|
2817
|
+
};
|
|
2818
|
+
return {
|
|
2819
|
+
messages,
|
|
2820
|
+
transform
|
|
2821
|
+
};
|
|
2822
|
+
}
|
|
2823
|
+
async getInvocableSkills(userContext = this.userContext, requestContext = {}) {
|
|
2824
|
+
const context = {
|
|
2825
|
+
...requestContext,
|
|
2826
|
+
_userContext: userContext
|
|
2827
|
+
};
|
|
2828
|
+
return listInvocableSkills((await this.getSkills()).filter((source) => source.authorize?.(context) !== false));
|
|
2829
|
+
}
|
|
2702
2830
|
async onChatResponse(result) {
|
|
2703
2831
|
this.analytics.turnCompleted(result.requestId, result.status, result.continuation, result.message.parts);
|
|
2704
2832
|
const parent = await this.getParentAgent();
|
|
@@ -2709,6 +2837,7 @@ var ChatAgent = class extends Agent {
|
|
|
2709
2837
|
if (!auth.success) return Response.json({ error: auth.message }, { status: auth.status });
|
|
2710
2838
|
const action = new URL(request.url).pathname.split("/").pop();
|
|
2711
2839
|
if (action === "getMessages" && request.method === "GET") return Response.json(await this.getMessages());
|
|
2840
|
+
if (action === "getInvocableSkills" && request.method === "GET") return Response.json(await this.getInvocableSkills(auth.userContext));
|
|
2712
2841
|
if (action === "sendMessage" && request.method === "POST") return this.streamMessage(request);
|
|
2713
2842
|
if (action === "cancelChat" && request.method === "POST") {
|
|
2714
2843
|
const { requestId } = await request.json();
|
|
@@ -2828,6 +2957,7 @@ function skill(definition) {
|
|
|
2828
2957
|
if (!definition.name) throw new Error("Skill name is required");
|
|
2829
2958
|
if (!definition.description) throw new Error("Skill description is required");
|
|
2830
2959
|
if (!definition.instructions) throw new Error("Skill content is required");
|
|
2960
|
+
if (definition.command !== void 0 && !/^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(definition.command)) throw new Error("Skill command must use lower-case letters, numbers, and hyphens");
|
|
2831
2961
|
return {
|
|
2832
2962
|
id: definition.name,
|
|
2833
2963
|
fingerprint: definition.name,
|
|
@@ -2845,6 +2975,7 @@ function skill(definition) {
|
|
|
2845
2975
|
body: definition.instructions
|
|
2846
2976
|
};
|
|
2847
2977
|
},
|
|
2978
|
+
command: definition.command,
|
|
2848
2979
|
tools: definition.tools,
|
|
2849
2980
|
actions: definition.actions,
|
|
2850
2981
|
authorize: definition.authorize,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@economic/agents",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.14.0",
|
|
4
4
|
"description": "A starter for creating a TypeScript package.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"files": [
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
},
|
|
46
46
|
"peerDependencies": {
|
|
47
47
|
"@cloudflare/think": "^0.17.0",
|
|
48
|
-
"@cloudflare/vite-plugin": "^1.
|
|
48
|
+
"@cloudflare/vite-plugin": "^1.45.1",
|
|
49
49
|
"@cloudflare/worker-bundler": "^0.2.1",
|
|
50
50
|
"agents": "^0.22.0",
|
|
51
51
|
"vite": ">=8.0.0"
|