kraken-ai 0.0.7 → 0.0.9

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 CHANGED
@@ -50,6 +50,40 @@ if (result.status === "complete") {
50
50
  }
51
51
  ```
52
52
 
53
+ ## Adding skills to a kernel
54
+
55
+ `defineSkillTool` and `skillDiscoveryMessage` give you the [Agent Skills](https://agentskills.io/specification) progressive-disclosure pattern with no framework lock-in. The SDK stays governance-agnostic — you wire the loader to whatever backend fetches the skill body (an in-memory map for tests, a file walker for a CLI, an authenticated service for production).
56
+
57
+ ```ts
58
+ import { Agent, defineSkillTool, skillDiscoveryMessage, openai } from "kraken-ai";
59
+
60
+ const SKILLS = {
61
+ "pdf-processing": "# PDF Processing\n\nUse pdfminer.six to extract …",
62
+ "csv-cleaning": "# CSV Cleaning\n\nNormalize headers via …",
63
+ };
64
+
65
+ const skillTools = Object.keys(SKILLS).map((id) =>
66
+ defineSkillTool({
67
+ skillId: id,
68
+ description: `Load the ${id} skill body`,
69
+ load: async (skillId) => SKILLS[skillId as keyof typeof SKILLS],
70
+ }),
71
+ );
72
+
73
+ const catalog = skillDiscoveryMessage([
74
+ { skillId: "pdf-processing", description: "Extract structured data from PDFs" },
75
+ { skillId: "csv-cleaning", description: "Normalize and dedupe CSVs" },
76
+ ]);
77
+
78
+ const agent = new Agent({
79
+ model: openai("gpt-4o"),
80
+ instructions: `You are a data assistant.\n\n${catalog}`,
81
+ tools: skillTools,
82
+ });
83
+ ```
84
+
85
+ Only the skill names + descriptions are in the system prompt at startup. The full skill body is loaded only when the model decides to call the matching `load_skill_*` tool.
86
+
53
87
  ## Documentation
54
88
 
55
89
  - [Models](docs/models.md) — providers, lazy resolution, custom providers
@@ -107,7 +107,7 @@ var buildRequestConfig = (params) => {
107
107
  if (params.maxOutputTokens != null) generateConfig.maxOutputTokens = params.maxOutputTokens;
108
108
  if (params.responseSchema) {
109
109
  generateConfig.responseMimeType = "application/json";
110
- generateConfig.responseSchema = params.responseSchema;
110
+ generateConfig.responseJsonSchema = params.responseSchema;
111
111
  }
112
112
  if (tools) generateConfig.tools = tools;
113
113
  return generateConfig;
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  google
3
- } from "./chunk-6Q6G4WVJ.js";
3
+ } from "./chunk-M2U6HNWW.js";
4
4
  import "./chunk-3WRAEJP3.js";
5
5
  export {
6
6
  google
package/dist/index.cjs CHANGED
@@ -204,7 +204,7 @@ var init_google = __esm({
204
204
  if (params.maxOutputTokens != null) generateConfig.maxOutputTokens = params.maxOutputTokens;
205
205
  if (params.responseSchema) {
206
206
  generateConfig.responseMimeType = "application/json";
207
- generateConfig.responseSchema = params.responseSchema;
207
+ generateConfig.responseJsonSchema = params.responseSchema;
208
208
  }
209
209
  if (tools) generateConfig.tools = tools;
210
210
  return generateConfig;
@@ -318,10 +318,12 @@ __export(index_exports, {
318
318
  ValidationError: () => ValidationError,
319
319
  configure: () => configure,
320
320
  defineKernel: () => defineKernel,
321
+ defineSkillTool: () => defineSkillTool,
321
322
  formatEvent: () => formatEvent,
322
323
  google: () => google,
323
324
  mock: () => mock,
324
325
  openai: () => openai,
326
+ skillDiscoveryMessage: () => skillDiscoveryMessage,
325
327
  tool: () => tool
326
328
  });
327
329
  module.exports = __toCommonJS(index_exports);
@@ -388,17 +390,12 @@ var z = __toESM(require("zod"), 1);
388
390
  var delegationSchema = z.object({
389
391
  task: z.string().describe("The task to delegate to this team member")
390
392
  });
391
- var createDelegationTools = (team, propagatedOptions, childRunIds) => team.map((member) => ({
393
+ var createDelegationTools = (team, propagatedOptions) => team.map((member) => ({
392
394
  name: `delegate_to_${member.name}`,
393
395
  description: member.description ?? `Delegate a task to ${member.name}`,
394
396
  execute: async (args) => {
395
397
  const { task } = delegationSchema.parse(args);
396
- const childRunId = childRunIds?.get(member.name)?.shift();
397
- const childOptions = {
398
- ...propagatedOptions,
399
- ...childRunId ? { runId: childRunId } : {}
400
- };
401
- const result = await member.run([{ role: "user", content: task }], childOptions);
398
+ const result = await member.run([{ role: "user", content: task }], propagatedOptions);
402
399
  if (result.status === "complete") return result.output;
403
400
  throw new Error(`Delegation to ${member.name} was interrupted`);
404
401
  },
@@ -697,7 +694,10 @@ var createRunner = (config2) => {
697
694
  }
698
695
  }
699
696
  }
700
- const executeFn = foundTool ? () => foundTool.execute(tc.args) : () => Promise.resolve(`Unknown tool: ${tc.name}`);
697
+ if (!foundTool) {
698
+ throw new ToolError(`Unknown tool: ${tc.name}`, tc.name);
699
+ }
700
+ const executeFn = () => foundTool.execute(tc.args);
701
701
  approved.push({ tc, executeFn });
702
702
  }
703
703
  if (!approved.length) continue;
@@ -707,18 +707,11 @@ var createRunner = (config2) => {
707
707
  for (const { tc } of approved) {
708
708
  if (tc.name.startsWith("delegate_to_")) {
709
709
  const targetName = tc.name.replace("delegate_to_", "");
710
- const childRunId = crypto.randomUUID();
711
710
  emitter.emit({
712
711
  type: "delegation",
713
- childRunId,
712
+ childRunId: crypto.randomUUID(),
714
713
  childAgentName: targetName
715
714
  });
716
- const queue = options?._childRunIds?.get(targetName);
717
- if (queue) {
718
- queue.push(childRunId);
719
- } else {
720
- options?._childRunIds?.set(targetName, [childRunId]);
721
- }
722
715
  }
723
716
  }
724
717
  }
@@ -906,7 +899,6 @@ var Agent = class {
906
899
  }
907
900
  const resolvedThinkingLevel = options?.thinkingLevel ?? this.config.thinkingLevel;
908
901
  const resolvedMaxOutputTokens = options?.maxOutputTokens ?? this.config.maxOutputTokens;
909
- const childRunIds = /* @__PURE__ */ new Map();
910
902
  if (this.config.team?.length) {
911
903
  const propagated = {
912
904
  middleware: options?.middleware,
@@ -917,7 +909,7 @@ var Agent = class {
917
909
  ...resolvedThinkingLevel ? { thinkingLevel: resolvedThinkingLevel } : {},
918
910
  ...resolvedMaxOutputTokens != null ? { maxOutputTokens: resolvedMaxOutputTokens } : {}
919
911
  };
920
- const delegationTools = createDelegationTools(this.config.team, propagated, childRunIds);
912
+ const delegationTools = createDelegationTools(this.config.team, propagated);
921
913
  allTools.push(...delegationTools);
922
914
  }
923
915
  const runner = createRunner({
@@ -934,7 +926,7 @@ var Agent = class {
934
926
  responseSchema: this.config.outputSchema ? z2.toJSONSchema(this.config.outputSchema, { target: "draft-2020-12" }) : void 0,
935
927
  logLevel: this.config.logLevel
936
928
  });
937
- const result = await runner.run(messages, { ...options, runId, _childRunIds: childRunIds });
929
+ const result = await runner.run(messages, { ...options, runId });
938
930
  if (result.status === "complete" && this.config.outputSchema) {
939
931
  const validated = await this.produceStructuredOutput(result, options);
940
932
  options?.onEvent?.({
@@ -1112,6 +1104,9 @@ var mock = (config2) => {
1112
1104
  // src/index.ts
1113
1105
  init_openai();
1114
1106
 
1107
+ // src/skills.ts
1108
+ var z4 = __toESM(require("zod"), 1);
1109
+
1115
1110
  // src/tool.ts
1116
1111
  var z3 = __toESM(require("zod"), 1);
1117
1112
  init_errors();
@@ -1152,6 +1147,43 @@ Hint: The LLM provided arguments that don't match the tool's parameter schema. T
1152
1147
  }
1153
1148
  };
1154
1149
  };
1150
+
1151
+ // src/skills.ts
1152
+ var skillContentBlock = (skillId, content) => `<skill_content name="${skillId}">
1153
+ ${content}
1154
+ </skill_content>`;
1155
+ var notLoadedMessage = (skillId) => `<skill_load_failed name="${skillId}">no content returned by loader</skill_load_failed>`;
1156
+ var defineSkillTool = (config2) => {
1157
+ const toolDescription = config2.description ?? (config2.displayName ? `Load the "${config2.displayName}" skill body.` : `Load the "${config2.skillId}" skill body.`);
1158
+ return tool({
1159
+ name: `load_skill_${config2.skillId.replace(/-/g, "_")}`,
1160
+ description: toolDescription,
1161
+ parameters: z4.object({
1162
+ args: z4.record(z4.string(), z4.unknown()).optional().describe("Optional arguments forwarded to the skill loader.")
1163
+ }),
1164
+ execute: async ({ args }) => {
1165
+ const content = await config2.load(config2.skillId, args);
1166
+ if (content === null || content === void 0) {
1167
+ return notLoadedMessage(config2.skillId);
1168
+ }
1169
+ return skillContentBlock(config2.skillId, content);
1170
+ }
1171
+ });
1172
+ };
1173
+ var skillDiscoveryMessage = (skills) => {
1174
+ if (skills.length === 0) return "";
1175
+ const blocks = skills.map((s) => {
1176
+ const name = s.displayName ?? s.skillId;
1177
+ return ` <skill id="${s.skillId}" name="${name}">${s.description}</skill>`;
1178
+ });
1179
+ return [
1180
+ "<available_skills>",
1181
+ ...blocks,
1182
+ "</available_skills>",
1183
+ "",
1184
+ "If a skill is relevant to the user's request, call its load tool to retrieve the full skill body before relying on it."
1185
+ ].join("\n");
1186
+ };
1155
1187
  // Annotate the CommonJS export names for ESM import in node:
1156
1188
  0 && (module.exports = {
1157
1189
  Agent,
@@ -1163,9 +1195,11 @@ Hint: The LLM provided arguments that don't match the tool's parameter schema. T
1163
1195
  ValidationError,
1164
1196
  configure,
1165
1197
  defineKernel,
1198
+ defineSkillTool,
1166
1199
  formatEvent,
1167
1200
  google,
1168
1201
  mock,
1169
1202
  openai,
1203
+ skillDiscoveryMessage,
1170
1204
  tool
1171
1205
  });
package/dist/index.d.cts CHANGED
@@ -389,8 +389,6 @@ interface RunOptions {
389
389
  responseSchema?: Record<string, unknown>;
390
390
  /** When true, tool calls are logged but not executed. */
391
391
  dryRun?: boolean;
392
- /** @internal Shared map for pre-generated child runIds during delegation. */
393
- _childRunIds?: Map<string, string[]>;
394
392
  }
395
393
  /** Specification for spawning a sub-agent from a kernel. */
396
394
  interface SpawnSpec {
@@ -646,6 +644,74 @@ declare const mock: (config?: MockModelConfig) => MockModel;
646
644
  */
647
645
  declare const openai: (_modelId: OpenAIModelId) => Model;
648
646
 
647
+ /**
648
+ * Configuration for {@link defineSkillTool}.
649
+ *
650
+ * @typeParam TLoadResult - Inferred return type of the `load` callback.
651
+ * Whatever the loader returns is wrapped in a `<skill_content>` block
652
+ * and returned to the LLM verbatim, so callers can shape the payload
653
+ * for their own progressive-disclosure tier.
654
+ */
655
+ interface SkillToolConfig {
656
+ /** Stable identifier for the skill — what the LLM passes back via the tool call. */
657
+ skillId: string;
658
+ /** Optional display name surfaced in the tool description. */
659
+ displayName?: string;
660
+ /** Short description rendered alongside the tool definition. */
661
+ description?: string;
662
+ /**
663
+ * Loader invoked when the LLM activates this skill. Receives the
664
+ * (already-validated) `skillId` and any opaque `args` the LLM passed.
665
+ * Returning a string sends it back as `<skill_content>` text; returning
666
+ * `null` / `undefined` short-circuits with a "not loaded" message.
667
+ */
668
+ load: (skillId: string, args?: Record<string, unknown>) => Promise<string | null | undefined>;
669
+ }
670
+ /**
671
+ * Build a `loadSkill`-style tool for an Agent that defers content fetch
672
+ * to a caller-provided `load` function. The engine stays governance-
673
+ * agnostic: production deployments wire `load` to call a governance
674
+ * gateway; tests can inline an in-memory loader; CLIs can read from disk.
675
+ *
676
+ * The returned tool accepts a single `args?: Record<string, unknown>`
677
+ * parameter — keep it permissive so end-user skills can describe their
678
+ * own argument shape inside the skill body without re-engineering this
679
+ * helper.
680
+ *
681
+ * @example
682
+ * ```ts
683
+ * const skillTool = defineSkillTool({
684
+ * skillId: "pdf-processing",
685
+ * description: "Loads the PDF processing skill body",
686
+ * load: async (id, args) => `# Skill body for ${id}: ${JSON.stringify(args)}`,
687
+ * });
688
+ * ```
689
+ */
690
+ declare const defineSkillTool: (config: SkillToolConfig) => Tool;
691
+ /**
692
+ * Catalog entry for {@link skillDiscoveryMessage}. Mirrors the Agent
693
+ * Skills spec's tier-1 metadata shape (~100 tokens per skill) — `name`
694
+ * + `description` only.
695
+ */
696
+ interface SkillCatalogEntry {
697
+ skillId: string;
698
+ description: string;
699
+ /** Optional display name; defaults to `skillId` when absent. */
700
+ displayName?: string;
701
+ }
702
+ /**
703
+ * Build a system-reminder string listing every available skill so the
704
+ * LLM can discover what's loadable before deciding to call `loadSkill`.
705
+ *
706
+ * Format follows the Agent Skills spec's recommended catalog wrapping —
707
+ * `<available_skills>` with one `<skill>` block per entry plus an
708
+ * instruction footer telling the model when to call the loader.
709
+ *
710
+ * Returns an empty string when `skills` is empty, so callers can drop
711
+ * the result into their system prompt unconditionally.
712
+ */
713
+ declare const skillDiscoveryMessage: (skills: ReadonlyArray<SkillCatalogEntry>) => string;
714
+
649
715
  /**
650
716
  * Configuration for creating a tool.
651
717
  *
@@ -696,4 +762,4 @@ interface ToolConfig<TParams extends z.ZodType, TReturn = unknown> {
696
762
  */
697
763
  declare const tool: <TParams extends z.ZodType, TReturn>(config: ToolConfig<TParams, TReturn>) => Tool;
698
764
 
699
- export { Agent, type AgentConfig, type AgentConfigEvent, type AgentDelegationEvent, type AgentErrorEvent, type AgentEvent, type AgentEventBase, type AgentEventPayload, type AgentEventType, type AgentInterruptEvent, type AgentKillEvent, type AgentLLMCallEvent, type AgentLifecycleEvent, type AgentLike, type AgentNotificationEvent, type AgentRef, type AgentState, type AgentStructuredOutputCompleteEvent, type AgentThoughtEvent, type AgentToolCallEvent, type AgentTranscriptInitEvent, type ExecutionContext, type GenerateParams, type GenerateResponse, type GlobalConfig, type GoogleModelConfig, type GoogleModelId, type HumanDecision, type Interrupt, type Kernel, type KernelSignal, KrakenError, type LogLevel, type Message, type Middleware, type MiddlewareContext, type Model, type ModelParams, type ModelString, type OpenAIModelId, OutputValidationError, ProviderError, type RetryConfig, type RunOptions, type RunResult, type RunnerResponse, type SpawnSpec, type StreamChunk, type TeamAccessor, type ThinkingLevel, type Tool, type ToolCall, type ToolConfig, type ToolDefinition, ToolError, ToolInputValidationError, type ToolResult, type TransitionRecord, type Usage, ValidationError, configure, defineKernel, formatEvent, google, mock, openai, tool };
765
+ export { Agent, type AgentConfig, type AgentConfigEvent, type AgentDelegationEvent, type AgentErrorEvent, type AgentEvent, type AgentEventBase, type AgentEventPayload, type AgentEventType, type AgentInterruptEvent, type AgentKillEvent, type AgentLLMCallEvent, type AgentLifecycleEvent, type AgentLike, type AgentNotificationEvent, type AgentRef, type AgentState, type AgentStructuredOutputCompleteEvent, type AgentThoughtEvent, type AgentToolCallEvent, type AgentTranscriptInitEvent, type ExecutionContext, type GenerateParams, type GenerateResponse, type GlobalConfig, type GoogleModelConfig, type GoogleModelId, type HumanDecision, type Interrupt, type Kernel, type KernelSignal, KrakenError, type LogLevel, type Message, type Middleware, type MiddlewareContext, type Model, type ModelParams, type ModelString, type OpenAIModelId, OutputValidationError, ProviderError, type RetryConfig, type RunOptions, type RunResult, type RunnerResponse, type SkillCatalogEntry, type SkillToolConfig, type SpawnSpec, type StreamChunk, type TeamAccessor, type ThinkingLevel, type Tool, type ToolCall, type ToolConfig, type ToolDefinition, ToolError, ToolInputValidationError, type ToolResult, type TransitionRecord, type Usage, ValidationError, configure, defineKernel, defineSkillTool, formatEvent, google, mock, openai, skillDiscoveryMessage, tool };
package/dist/index.d.ts CHANGED
@@ -389,8 +389,6 @@ interface RunOptions {
389
389
  responseSchema?: Record<string, unknown>;
390
390
  /** When true, tool calls are logged but not executed. */
391
391
  dryRun?: boolean;
392
- /** @internal Shared map for pre-generated child runIds during delegation. */
393
- _childRunIds?: Map<string, string[]>;
394
392
  }
395
393
  /** Specification for spawning a sub-agent from a kernel. */
396
394
  interface SpawnSpec {
@@ -646,6 +644,74 @@ declare const mock: (config?: MockModelConfig) => MockModel;
646
644
  */
647
645
  declare const openai: (_modelId: OpenAIModelId) => Model;
648
646
 
647
+ /**
648
+ * Configuration for {@link defineSkillTool}.
649
+ *
650
+ * @typeParam TLoadResult - Inferred return type of the `load` callback.
651
+ * Whatever the loader returns is wrapped in a `<skill_content>` block
652
+ * and returned to the LLM verbatim, so callers can shape the payload
653
+ * for their own progressive-disclosure tier.
654
+ */
655
+ interface SkillToolConfig {
656
+ /** Stable identifier for the skill — what the LLM passes back via the tool call. */
657
+ skillId: string;
658
+ /** Optional display name surfaced in the tool description. */
659
+ displayName?: string;
660
+ /** Short description rendered alongside the tool definition. */
661
+ description?: string;
662
+ /**
663
+ * Loader invoked when the LLM activates this skill. Receives the
664
+ * (already-validated) `skillId` and any opaque `args` the LLM passed.
665
+ * Returning a string sends it back as `<skill_content>` text; returning
666
+ * `null` / `undefined` short-circuits with a "not loaded" message.
667
+ */
668
+ load: (skillId: string, args?: Record<string, unknown>) => Promise<string | null | undefined>;
669
+ }
670
+ /**
671
+ * Build a `loadSkill`-style tool for an Agent that defers content fetch
672
+ * to a caller-provided `load` function. The engine stays governance-
673
+ * agnostic: production deployments wire `load` to call a governance
674
+ * gateway; tests can inline an in-memory loader; CLIs can read from disk.
675
+ *
676
+ * The returned tool accepts a single `args?: Record<string, unknown>`
677
+ * parameter — keep it permissive so end-user skills can describe their
678
+ * own argument shape inside the skill body without re-engineering this
679
+ * helper.
680
+ *
681
+ * @example
682
+ * ```ts
683
+ * const skillTool = defineSkillTool({
684
+ * skillId: "pdf-processing",
685
+ * description: "Loads the PDF processing skill body",
686
+ * load: async (id, args) => `# Skill body for ${id}: ${JSON.stringify(args)}`,
687
+ * });
688
+ * ```
689
+ */
690
+ declare const defineSkillTool: (config: SkillToolConfig) => Tool;
691
+ /**
692
+ * Catalog entry for {@link skillDiscoveryMessage}. Mirrors the Agent
693
+ * Skills spec's tier-1 metadata shape (~100 tokens per skill) — `name`
694
+ * + `description` only.
695
+ */
696
+ interface SkillCatalogEntry {
697
+ skillId: string;
698
+ description: string;
699
+ /** Optional display name; defaults to `skillId` when absent. */
700
+ displayName?: string;
701
+ }
702
+ /**
703
+ * Build a system-reminder string listing every available skill so the
704
+ * LLM can discover what's loadable before deciding to call `loadSkill`.
705
+ *
706
+ * Format follows the Agent Skills spec's recommended catalog wrapping —
707
+ * `<available_skills>` with one `<skill>` block per entry plus an
708
+ * instruction footer telling the model when to call the loader.
709
+ *
710
+ * Returns an empty string when `skills` is empty, so callers can drop
711
+ * the result into their system prompt unconditionally.
712
+ */
713
+ declare const skillDiscoveryMessage: (skills: ReadonlyArray<SkillCatalogEntry>) => string;
714
+
649
715
  /**
650
716
  * Configuration for creating a tool.
651
717
  *
@@ -696,4 +762,4 @@ interface ToolConfig<TParams extends z.ZodType, TReturn = unknown> {
696
762
  */
697
763
  declare const tool: <TParams extends z.ZodType, TReturn>(config: ToolConfig<TParams, TReturn>) => Tool;
698
764
 
699
- export { Agent, type AgentConfig, type AgentConfigEvent, type AgentDelegationEvent, type AgentErrorEvent, type AgentEvent, type AgentEventBase, type AgentEventPayload, type AgentEventType, type AgentInterruptEvent, type AgentKillEvent, type AgentLLMCallEvent, type AgentLifecycleEvent, type AgentLike, type AgentNotificationEvent, type AgentRef, type AgentState, type AgentStructuredOutputCompleteEvent, type AgentThoughtEvent, type AgentToolCallEvent, type AgentTranscriptInitEvent, type ExecutionContext, type GenerateParams, type GenerateResponse, type GlobalConfig, type GoogleModelConfig, type GoogleModelId, type HumanDecision, type Interrupt, type Kernel, type KernelSignal, KrakenError, type LogLevel, type Message, type Middleware, type MiddlewareContext, type Model, type ModelParams, type ModelString, type OpenAIModelId, OutputValidationError, ProviderError, type RetryConfig, type RunOptions, type RunResult, type RunnerResponse, type SpawnSpec, type StreamChunk, type TeamAccessor, type ThinkingLevel, type Tool, type ToolCall, type ToolConfig, type ToolDefinition, ToolError, ToolInputValidationError, type ToolResult, type TransitionRecord, type Usage, ValidationError, configure, defineKernel, formatEvent, google, mock, openai, tool };
765
+ export { Agent, type AgentConfig, type AgentConfigEvent, type AgentDelegationEvent, type AgentErrorEvent, type AgentEvent, type AgentEventBase, type AgentEventPayload, type AgentEventType, type AgentInterruptEvent, type AgentKillEvent, type AgentLLMCallEvent, type AgentLifecycleEvent, type AgentLike, type AgentNotificationEvent, type AgentRef, type AgentState, type AgentStructuredOutputCompleteEvent, type AgentThoughtEvent, type AgentToolCallEvent, type AgentTranscriptInitEvent, type ExecutionContext, type GenerateParams, type GenerateResponse, type GlobalConfig, type GoogleModelConfig, type GoogleModelId, type HumanDecision, type Interrupt, type Kernel, type KernelSignal, KrakenError, type LogLevel, type Message, type Middleware, type MiddlewareContext, type Model, type ModelParams, type ModelString, type OpenAIModelId, OutputValidationError, ProviderError, type RetryConfig, type RunOptions, type RunResult, type RunnerResponse, type SkillCatalogEntry, type SkillToolConfig, type SpawnSpec, type StreamChunk, type TeamAccessor, type ThinkingLevel, type Tool, type ToolCall, type ToolConfig, type ToolDefinition, ToolError, ToolInputValidationError, type ToolResult, type TransitionRecord, type Usage, ValidationError, configure, defineKernel, defineSkillTool, formatEvent, google, mock, openai, skillDiscoveryMessage, tool };
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  google
3
- } from "./chunk-6Q6G4WVJ.js";
3
+ } from "./chunk-M2U6HNWW.js";
4
4
  import {
5
5
  openai
6
6
  } from "./chunk-D2AU5FGJ.js";
@@ -40,7 +40,7 @@ var createLazyModel = (provider, modelId) => {
40
40
  const ensureResolved = async () => {
41
41
  if (resolvedModel) return resolvedModel;
42
42
  if (provider === "google") {
43
- const { google: google2 } = await import("./google-W6HDKXTM.js");
43
+ const { google: google2 } = await import("./google-3DFIROPW.js");
44
44
  resolvedModel = google2(modelId);
45
45
  } else if (provider === "openai") {
46
46
  const { openai: openai2 } = await import("./openai-STUANOLN.js");
@@ -73,17 +73,12 @@ import * as z from "zod";
73
73
  var delegationSchema = z.object({
74
74
  task: z.string().describe("The task to delegate to this team member")
75
75
  });
76
- var createDelegationTools = (team, propagatedOptions, childRunIds) => team.map((member) => ({
76
+ var createDelegationTools = (team, propagatedOptions) => team.map((member) => ({
77
77
  name: `delegate_to_${member.name}`,
78
78
  description: member.description ?? `Delegate a task to ${member.name}`,
79
79
  execute: async (args) => {
80
80
  const { task } = delegationSchema.parse(args);
81
- const childRunId = childRunIds?.get(member.name)?.shift();
82
- const childOptions = {
83
- ...propagatedOptions,
84
- ...childRunId ? { runId: childRunId } : {}
85
- };
86
- const result = await member.run([{ role: "user", content: task }], childOptions);
81
+ const result = await member.run([{ role: "user", content: task }], propagatedOptions);
87
82
  if (result.status === "complete") return result.output;
88
83
  throw new Error(`Delegation to ${member.name} was interrupted`);
89
84
  },
@@ -379,7 +374,10 @@ var createRunner = (config2) => {
379
374
  }
380
375
  }
381
376
  }
382
- const executeFn = foundTool ? () => foundTool.execute(tc.args) : () => Promise.resolve(`Unknown tool: ${tc.name}`);
377
+ if (!foundTool) {
378
+ throw new ToolError(`Unknown tool: ${tc.name}`, tc.name);
379
+ }
380
+ const executeFn = () => foundTool.execute(tc.args);
383
381
  approved.push({ tc, executeFn });
384
382
  }
385
383
  if (!approved.length) continue;
@@ -389,18 +387,11 @@ var createRunner = (config2) => {
389
387
  for (const { tc } of approved) {
390
388
  if (tc.name.startsWith("delegate_to_")) {
391
389
  const targetName = tc.name.replace("delegate_to_", "");
392
- const childRunId = crypto.randomUUID();
393
390
  emitter.emit({
394
391
  type: "delegation",
395
- childRunId,
392
+ childRunId: crypto.randomUUID(),
396
393
  childAgentName: targetName
397
394
  });
398
- const queue = options?._childRunIds?.get(targetName);
399
- if (queue) {
400
- queue.push(childRunId);
401
- } else {
402
- options?._childRunIds?.set(targetName, [childRunId]);
403
- }
404
395
  }
405
396
  }
406
397
  }
@@ -588,7 +579,6 @@ var Agent = class {
588
579
  }
589
580
  const resolvedThinkingLevel = options?.thinkingLevel ?? this.config.thinkingLevel;
590
581
  const resolvedMaxOutputTokens = options?.maxOutputTokens ?? this.config.maxOutputTokens;
591
- const childRunIds = /* @__PURE__ */ new Map();
592
582
  if (this.config.team?.length) {
593
583
  const propagated = {
594
584
  middleware: options?.middleware,
@@ -599,7 +589,7 @@ var Agent = class {
599
589
  ...resolvedThinkingLevel ? { thinkingLevel: resolvedThinkingLevel } : {},
600
590
  ...resolvedMaxOutputTokens != null ? { maxOutputTokens: resolvedMaxOutputTokens } : {}
601
591
  };
602
- const delegationTools = createDelegationTools(this.config.team, propagated, childRunIds);
592
+ const delegationTools = createDelegationTools(this.config.team, propagated);
603
593
  allTools.push(...delegationTools);
604
594
  }
605
595
  const runner = createRunner({
@@ -616,7 +606,7 @@ var Agent = class {
616
606
  responseSchema: this.config.outputSchema ? z2.toJSONSchema(this.config.outputSchema, { target: "draft-2020-12" }) : void 0,
617
607
  logLevel: this.config.logLevel
618
608
  });
619
- const result = await runner.run(messages, { ...options, runId, _childRunIds: childRunIds });
609
+ const result = await runner.run(messages, { ...options, runId });
620
610
  if (result.status === "complete" && this.config.outputSchema) {
621
611
  const validated = await this.produceStructuredOutput(result, options);
622
612
  options?.onEvent?.({
@@ -785,6 +775,9 @@ var mock = (config2) => {
785
775
  };
786
776
  };
787
777
 
778
+ // src/skills.ts
779
+ import * as z4 from "zod";
780
+
788
781
  // src/tool.ts
789
782
  import * as z3 from "zod";
790
783
  var tool = (config2) => {
@@ -824,6 +817,43 @@ Hint: The LLM provided arguments that don't match the tool's parameter schema. T
824
817
  }
825
818
  };
826
819
  };
820
+
821
+ // src/skills.ts
822
+ var skillContentBlock = (skillId, content) => `<skill_content name="${skillId}">
823
+ ${content}
824
+ </skill_content>`;
825
+ var notLoadedMessage = (skillId) => `<skill_load_failed name="${skillId}">no content returned by loader</skill_load_failed>`;
826
+ var defineSkillTool = (config2) => {
827
+ const toolDescription = config2.description ?? (config2.displayName ? `Load the "${config2.displayName}" skill body.` : `Load the "${config2.skillId}" skill body.`);
828
+ return tool({
829
+ name: `load_skill_${config2.skillId.replace(/-/g, "_")}`,
830
+ description: toolDescription,
831
+ parameters: z4.object({
832
+ args: z4.record(z4.string(), z4.unknown()).optional().describe("Optional arguments forwarded to the skill loader.")
833
+ }),
834
+ execute: async ({ args }) => {
835
+ const content = await config2.load(config2.skillId, args);
836
+ if (content === null || content === void 0) {
837
+ return notLoadedMessage(config2.skillId);
838
+ }
839
+ return skillContentBlock(config2.skillId, content);
840
+ }
841
+ });
842
+ };
843
+ var skillDiscoveryMessage = (skills) => {
844
+ if (skills.length === 0) return "";
845
+ const blocks = skills.map((s) => {
846
+ const name = s.displayName ?? s.skillId;
847
+ return ` <skill id="${s.skillId}" name="${name}">${s.description}</skill>`;
848
+ });
849
+ return [
850
+ "<available_skills>",
851
+ ...blocks,
852
+ "</available_skills>",
853
+ "",
854
+ "If a skill is relevant to the user's request, call its load tool to retrieve the full skill body before relying on it."
855
+ ].join("\n");
856
+ };
827
857
  export {
828
858
  Agent,
829
859
  KrakenError,
@@ -834,9 +864,11 @@ export {
834
864
  ValidationError,
835
865
  configure,
836
866
  defineKernel,
867
+ defineSkillTool,
837
868
  formatEvent,
838
869
  google,
839
870
  mock,
840
871
  openai,
872
+ skillDiscoveryMessage,
841
873
  tool
842
874
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kraken-ai",
3
- "version": "0.0.7",
3
+ "version": "0.0.9",
4
4
  "description": "Kraken AI SDK: a very lightweight, fully-typed multi-model AI agent framework",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -14,16 +14,16 @@
14
14
  }
15
15
  },
16
16
  "devDependencies": {
17
- "@google/genai": "^1.48.0",
18
- "@types/node": "^25.5.2",
17
+ "@google/genai": "^1.50.1",
18
+ "@types/node": "^25.6.0",
19
19
  "tsup": "^8.5.1",
20
20
  "tsx": "^4.21.0",
21
- "typescript": "^6.0.2",
22
- "vitest": "^4.1.3",
21
+ "typescript": "^6.0.3",
22
+ "vitest": "^4.1.5",
23
23
  "zod": "^4.3.6"
24
24
  },
25
25
  "peerDependencies": {
26
- "@google/genai": ">=1.0.0",
26
+ "@google/genai": "^1.50.1",
27
27
  "zod": "^4.0.0"
28
28
  },
29
29
  "peerDependenciesMeta": {