@theokit/sdk 2.19.0 → 2.20.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/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # Changelog
2
2
 
3
+ ## 2.20.0
4
+
5
+ ### Minor Changes
6
+
7
+ - **M21 — `GenerateObjectOptions.structuringModel`.** An optional separate model for the structured-extraction step: when set, `model` first produces a free-text reasoned answer (phase 1), then `structuringModel` extracts the schema-matched object by calling the synthetic `output` tool over that answer (phase 2). Lets a large model reason while a cheap fast model structures. Absent ⇒ today's single-model flow (backward-compatible). Proven by a golden test asserting two distinct model ids in the run.
8
+ - **M22 — `createSkill()` + `SkillsSettings.skillsDir` / `.inline`.** `createSkill({ name, description, instructions })` defines a skill in TypeScript without a `SKILL.md` file; pass code-defined skills via `skills.inline` (they surface in `list()` + the `<skills>` block alongside filesystem skills, overriding a file skill of the same name). `skills.skillsDir` discovers skills from a custom directory instead of `<cwd>/.theokit/skills`. Both compose with the per-request enabled-name resolver.
9
+ - **M23 — `normalizeSchema()`.** Converts a schema from Zod (default), JSON Schema (passthrough), ArkType (`.toJsonSchema()`), or Valibot (via the optional `@valibot/to-json-schema` peer) to the internal JSON Schema the synthetic `output` tool uses. Zod stays the default and the documented recommendation; thin adapter, uniform parse-failure handling. A golden test per provider.
10
+
3
11
  ## 2.19.0
4
12
 
5
13
  ### Minor Changes
@@ -6807,23 +6807,27 @@ var init_skills_manager = __esm({
6807
6807
  "src/internal/runtime/skills/skills-manager.ts"() {
6808
6808
  init_discover_skills();
6809
6809
  SkillsManager = class {
6810
- constructor(cwd, _enabled, settingSourcesIncludeProject) {
6810
+ constructor(cwd, _enabled, settingSourcesIncludeProject, skillsDir, inline) {
6811
6811
  this.cwd = cwd;
6812
6812
  this.settingSourcesIncludeProject = settingSourcesIncludeProject;
6813
+ this.skillsDir = skillsDir;
6814
+ this.inline = inline;
6813
6815
  }
6814
6816
  cwd;
6815
6817
  settingSourcesIncludeProject;
6818
+ skillsDir;
6819
+ inline;
6816
6820
  skills = [];
6817
6821
  async initialize() {
6818
6822
  if (!this.settingSourcesIncludeProject) {
6819
- this.skills = [];
6823
+ this.skills = this.mergeInline([]);
6820
6824
  return;
6821
6825
  }
6822
6826
  await this.refresh();
6823
6827
  }
6824
6828
  async refresh() {
6825
- const skillsRoot = path.join(this.cwd, ".theokit", "skills");
6826
- this.skills = await discoverSkills(skillsRoot, {
6829
+ const skillsRoot = this.skillsDir ?? path.join(this.cwd, ".theokit", "skills");
6830
+ const discovered = await discoverSkills(skillsRoot, {
6827
6831
  onInvalidSkill: (info) => {
6828
6832
  process.stderr.write(
6829
6833
  `[theokit-sdk] skill ${info.name} skipped (${info.code}): ${info.message}
@@ -6831,6 +6835,13 @@ var init_skills_manager = __esm({
6831
6835
  );
6832
6836
  }
6833
6837
  });
6838
+ this.skills = this.mergeInline(discovered);
6839
+ }
6840
+ /** M22 — merge inline skills over discovered ones; inline wins on a name conflict. */
6841
+ mergeInline(discovered) {
6842
+ if (this.inline === void 0 || this.inline.length === 0) return discovered;
6843
+ const inlineNames = new Set(this.inline.map((s) => s.name));
6844
+ return [...discovered.filter((s) => !inlineNames.has(s.name)), ...this.inline];
6834
6845
  }
6835
6846
  list() {
6836
6847
  return Promise.resolve(this.skills);
@@ -6877,7 +6888,10 @@ function bootstrapSubmanagers(args) {
6877
6888
  out.skillsManager = new SkillsManager(
6878
6889
  args.workspaceCwd,
6879
6890
  args.options.skills?.enabled,
6880
- args.settingSourcesIncludeProject
6891
+ args.settingSourcesIncludeProject,
6892
+ // M22 — custom skills directory + inline (code-defined) skills.
6893
+ args.options.skills?.skillsDir,
6894
+ args.options.skills?.inline
6881
6895
  );
6882
6896
  const localSkills = out.skillsManager;
6883
6897
  out.skills = { list: () => localSkills.list() };
@@ -17170,6 +17184,24 @@ function salvagePartial(schema, raw) {
17170
17184
  }
17171
17185
  return out;
17172
17186
  }
17187
+ async function runReasoningPhase(options, deps) {
17188
+ const reasoningOptions = {
17189
+ model: options.model,
17190
+ local: options.local,
17191
+ ...options.systemPrompt !== void 0 ? { systemPrompt: options.systemPrompt } : {},
17192
+ ...options.apiKey !== void 0 ? { apiKey: options.apiKey } : {},
17193
+ ...options.providers !== void 0 ? { providers: options.providers } : {}
17194
+ };
17195
+ const reasoningAgent = await deps.create(reasoningOptions);
17196
+ try {
17197
+ const run = await reasoningAgent.send(options.prompt);
17198
+ const result = await run.wait();
17199
+ const text = result.result;
17200
+ return typeof text === "string" ? text : options.prompt;
17201
+ } finally {
17202
+ await disposeAndDeleteTransient(reasoningAgent, deps.delete);
17203
+ }
17204
+ }
17173
17205
  async function generateObjectImpl(options, deps) {
17174
17206
  const { jsonSchema, maxRetries, initialUsage } = setupStructuredOutput(
17175
17207
  options.schema,
@@ -17192,8 +17224,11 @@ async function generateObjectImpl(options, deps) {
17192
17224
  }
17193
17225
  throw new CaptureSentinel(input);
17194
17226
  });
17227
+ const reasoningText = options.structuringModel !== void 0 ? await runReasoningPhase(options, deps) : void 0;
17228
+ const structuringModel = options.structuringModel ?? options.model;
17229
+ const structuringPrompt = reasoningText ?? options.prompt;
17195
17230
  const agentOptions = buildTransientAgentOptions({
17196
- model: options.model,
17231
+ model: structuringModel,
17197
17232
  local: options.local,
17198
17233
  outputTool,
17199
17234
  ...options.systemPrompt !== void 0 ? { systemPrompt: options.systemPrompt } : {},
@@ -17202,7 +17237,7 @@ async function generateObjectImpl(options, deps) {
17202
17237
  });
17203
17238
  const agent = await deps.create(agentOptions);
17204
17239
  try {
17205
- const userMessage = buildToolPrompt(options.prompt);
17240
+ const userMessage = buildToolPrompt(structuringPrompt);
17206
17241
  let lastParseError;
17207
17242
  for (let attempt = 0; attempt <= maxRetries; attempt += 1) {
17208
17243
  capturedRaw = void 0;