@soederpop/luca 0.0.28 → 0.0.29

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.
@@ -1,5 +1,5 @@
1
1
  // Auto-generated bootstrap content
2
- // Generated at: 2026-03-23T07:45:58.711Z
2
+ // Generated at: 2026-03-24T01:41:40.771Z
3
3
  // Source: docs/bootstrap/*.md, docs/bootstrap/templates/*, docs/examples/*.md, docs/tutorials/*.md
4
4
  //
5
5
  // Do not edit manually. Run: luca build-bootstrap
@@ -1633,6 +1633,151 @@ for (const raw of commands) {
1633
1633
  ## Summary
1634
1634
 
1635
1635
  This demo covered the three main methods of the \`nlp\` feature: \`parse()\` for quick structural extraction from voice commands, \`analyze()\` for detailed POS tagging and entity recognition, and \`understand()\` for a combined view of both. The feature is well suited for building voice command interpreters, chatbot intent classifiers, and text analysis pipelines.
1636
+ `,
1637
+ "structured-output-with-assistants.md": `---
1638
+ title: "Structured Output with Assistants"
1639
+ tags: [assistant, conversation, structured-output, zod, openai]
1640
+ lastTested: null
1641
+ lastTestPassed: null
1642
+ ---
1643
+
1644
+ # Structured Output with Assistants
1645
+
1646
+ Get typed, schema-validated JSON responses from OpenAI instead of raw text strings.
1647
+
1648
+ ## Overview
1649
+
1650
+ OpenAI's Structured Outputs feature constrains the model to return JSON that exactly matches a schema you provide. Combined with Zod, this means \`ask()\` can return parsed objects instead of strings — no regex parsing, no "please respond in JSON", no malformed output.
1651
+
1652
+ Pass a \`schema\` option to \`ask()\` and the response comes back as a parsed object guaranteed to match your schema.
1653
+
1654
+ ## Basic: Extract Structured Data
1655
+
1656
+ The simplest use case — ask a question and get structured data back.
1657
+
1658
+ \`\`\`ts
1659
+ const { z } = container
1660
+ const conversation = container.feature('conversation', {
1661
+ model: 'gpt-4.1-mini',
1662
+ history: [{ role: 'system', content: 'You are a helpful data extraction assistant.' }]
1663
+ })
1664
+
1665
+ const result = await conversation.ask('The founders of Apple are Steve Jobs, Steve Wozniak, and Ronald Wayne. They started it in 1976 in Los Altos, California.', {
1666
+ schema: z.object({
1667
+ company: z.string(),
1668
+ foundedYear: z.number(),
1669
+ location: z.string(),
1670
+ founders: z.array(z.string()),
1671
+ }).describe('CompanyInfo')
1672
+ })
1673
+
1674
+ console.log('Company:', result.company)
1675
+ console.log('Founded:', result.foundedYear)
1676
+ console.log('Location:', result.location)
1677
+ console.log('Founders:', result.founders)
1678
+ \`\`\`
1679
+
1680
+ The \`.describe()\` on the schema gives OpenAI the schema name — keep it short and descriptive.
1681
+
1682
+ ## Enums and Categorization
1683
+
1684
+ Structured outputs work great for classification tasks where you want the model to pick from a fixed set of values.
1685
+
1686
+ \`\`\`ts
1687
+ const { z } = container
1688
+ const conversation = container.feature('conversation', {
1689
+ model: 'gpt-4.1-mini',
1690
+ history: [{ role: 'system', content: 'You are a helpful assistant.' }]
1691
+ })
1692
+
1693
+ const sentiment = await conversation.ask('I absolutely love this product, it changed my life!', {
1694
+ schema: z.object({
1695
+ sentiment: z.enum(['positive', 'negative', 'neutral', 'mixed']),
1696
+ confidence: z.number(),
1697
+ reasoning: z.string(),
1698
+ }).describe('SentimentAnalysis')
1699
+ })
1700
+
1701
+ console.log('Sentiment:', sentiment.sentiment)
1702
+ console.log('Confidence:', sentiment.confidence)
1703
+ console.log('Reasoning:', sentiment.reasoning)
1704
+ \`\`\`
1705
+
1706
+ Because the model is constrained by the schema, \`sentiment\` will always be one of the four allowed values.
1707
+
1708
+ ## Nested Objects and Arrays
1709
+
1710
+ Schemas can be as complex as you need. Here we extract a structured analysis with nested objects.
1711
+
1712
+ \`\`\`ts
1713
+ const { z } = container
1714
+ const conversation = container.feature('conversation', {
1715
+ model: 'gpt-4.1-mini',
1716
+ history: [{ role: 'system', content: 'You are a technical analyst.' }]
1717
+ })
1718
+
1719
+ const analysis = await conversation.ask(
1720
+ 'TypeScript 5.5 introduced inferred type predicates, which automatically narrow types in filter callbacks. It also added isolated declarations for faster builds in monorepos, and a new regex syntax checking feature.',
1721
+ {
1722
+ schema: z.object({
1723
+ subject: z.string(),
1724
+ version: z.string(),
1725
+ features: z.array(z.object({
1726
+ name: z.string(),
1727
+ category: z.enum(['type-system', 'performance', 'developer-experience', 'syntax', 'other']),
1728
+ summary: z.string(),
1729
+ })),
1730
+ featureCount: z.number(),
1731
+ }).describe('ReleaseAnalysis')
1732
+ }
1733
+ )
1734
+
1735
+ console.log('Subject:', analysis.subject, analysis.version)
1736
+ console.log('Features:')
1737
+ for (const f of analysis.features) {
1738
+ console.log(\` [\${f.category}] \${f.name}: \${f.summary}\`)
1739
+ }
1740
+ console.log('Total features:', analysis.featureCount)
1741
+ \`\`\`
1742
+
1743
+ Every level of nesting is validated — the model cannot return a feature without a category or skip required fields.
1744
+
1745
+ ## With an Assistant
1746
+
1747
+ Structured outputs work the same way through the assistant API. The schema passes straight through to the underlying conversation.
1748
+
1749
+ \`\`\`ts
1750
+ const { z } = container
1751
+ const assistant = container.feature('assistant', {
1752
+ systemPrompt: 'You are a code review assistant. You analyze code snippets and provide structured feedback.',
1753
+ model: 'gpt-4.1-mini',
1754
+ })
1755
+
1756
+ const review = await assistant.ask(
1757
+ 'Review this: function add(a, b) { return a + b }',
1758
+ {
1759
+ schema: z.object({
1760
+ issues: z.array(z.object({
1761
+ severity: z.enum(['info', 'warning', 'error']),
1762
+ message: z.string(),
1763
+ })),
1764
+ suggestion: z.string(),
1765
+ score: z.number(),
1766
+ }).describe('CodeReview')
1767
+ }
1768
+ )
1769
+
1770
+ console.log('Score:', review.score)
1771
+ console.log('Suggestion:', review.suggestion)
1772
+ console.log('Issues:')
1773
+ for (const issue of review.issues) {
1774
+ console.log(\` [\${issue.severity}] \${issue.message}\`)
1775
+ }
1776
+ \`\`\`
1777
+
1778
+ ## Summary
1779
+
1780
+ This demo covered extracting structured data, classification with enums, nested schema validation, and using structured outputs through both the conversation and assistant APIs. The key is passing a Zod schema via \`{ schema }\` in the options to \`ask()\` — OpenAI guarantees the response matches, and you get a parsed object back.
1636
1781
  `,
1637
1782
  "networking.md": `---
1638
1783
  title: "networking"
@@ -1,4 +1,4 @@
1
1
  // Generated at compile time — do not edit manually
2
2
  export const BUILD_SHA = 'c1e466d'
3
3
  export const BUILD_BRANCH = 'main'
4
- export const BUILD_DATE = '2026-03-23T07:45:58Z'
4
+ export const BUILD_DATE = '2026-03-24T01:41:40Z'
@@ -1,7 +1,7 @@
1
1
  import { setBuildTimeData, setContainerBuildTimeData } from './index.js';
2
2
 
3
3
  // Auto-generated introspection registry data
4
- // Generated at: 2026-03-23T07:45:57.079Z
4
+ // Generated at: 2026-03-24T01:41:39.242Z
5
5
 
6
6
  setBuildTimeData('features.googleDocs', {
7
7
  "id": "features.googleDocs",
@@ -5773,6 +5773,32 @@ setBuildTimeData('features.fs', {
5773
5773
  }
5774
5774
  ]
5775
5775
  },
5776
+ "isSymlink": {
5777
+ "description": "Checks if a path is a symbolic link.",
5778
+ "parameters": {
5779
+ "path": {
5780
+ "type": "string",
5781
+ "description": "The path to check"
5782
+ }
5783
+ },
5784
+ "required": [
5785
+ "path"
5786
+ ],
5787
+ "returns": "boolean"
5788
+ },
5789
+ "realpath": {
5790
+ "description": "Resolves a symlink to its real path. Returns the resolved path as-is if not a symlink.",
5791
+ "parameters": {
5792
+ "path": {
5793
+ "type": "string",
5794
+ "description": "The path to resolve"
5795
+ }
5796
+ },
5797
+ "required": [
5798
+ "path"
5799
+ ],
5800
+ "returns": "string"
5801
+ },
5776
5802
  "stat": {
5777
5803
  "description": "Synchronously returns the stat object for a file or directory.",
5778
5804
  "parameters": {
@@ -11690,6 +11716,10 @@ setBuildTimeData('features.conversation', {
11690
11716
  "maxTokens": {
11691
11717
  "type": "number",
11692
11718
  "description": ""
11719
+ },
11720
+ "schema": {
11721
+ "type": "z.ZodType",
11722
+ "description": "When provided, enables OpenAI Structured Outputs. The model is constrained to return JSON matching this Zod schema. The return value of ask() will be the parsed object instead of a raw string."
11693
11723
  }
11694
11724
  }
11695
11725
  }
@@ -11807,6 +11837,21 @@ setBuildTimeData('features.conversation', {
11807
11837
  "description": "Event emitted by Conversation",
11808
11838
  "arguments": {}
11809
11839
  },
11840
+ "toolError": {
11841
+ "name": "toolError",
11842
+ "description": "Event emitted by Conversation",
11843
+ "arguments": {}
11844
+ },
11845
+ "toolCall": {
11846
+ "name": "toolCall",
11847
+ "description": "Event emitted by Conversation",
11848
+ "arguments": {}
11849
+ },
11850
+ "toolResult": {
11851
+ "name": "toolResult",
11852
+ "description": "Event emitted by Conversation",
11853
+ "arguments": {}
11854
+ },
11810
11855
  "turnStart": {
11811
11856
  "name": "turnStart",
11812
11857
  "description": "Event emitted by Conversation",
@@ -11842,21 +11887,6 @@ setBuildTimeData('features.conversation', {
11842
11887
  "description": "Event emitted by Conversation",
11843
11888
  "arguments": {}
11844
11889
  },
11845
- "toolError": {
11846
- "name": "toolError",
11847
- "description": "Event emitted by Conversation",
11848
- "arguments": {}
11849
- },
11850
- "toolCall": {
11851
- "name": "toolCall",
11852
- "description": "Event emitted by Conversation",
11853
- "arguments": {}
11854
- },
11855
- "toolResult": {
11856
- "name": "toolResult",
11857
- "description": "Event emitted by Conversation",
11858
- "arguments": {}
11859
- },
11860
11890
  "toolCallsEnd": {
11861
11891
  "name": "toolCallsEnd",
11862
11892
  "description": "Event emitted by Conversation",
@@ -12276,6 +12306,24 @@ setBuildTimeData('features.assistant', {
12276
12306
  "shortcut": "features.assistant",
12277
12307
  "className": "Assistant",
12278
12308
  "methods": {
12309
+ "intercept": {
12310
+ "description": "Register an interceptor at a given point in the pipeline.",
12311
+ "parameters": {
12312
+ "point": {
12313
+ "type": "K",
12314
+ "description": "The interception point"
12315
+ },
12316
+ "fn": {
12317
+ "type": "InterceptorFn<InterceptorPoints[K]>",
12318
+ "description": "Middleware function receiving (ctx, next)"
12319
+ }
12320
+ },
12321
+ "required": [
12322
+ "point",
12323
+ "fn"
12324
+ ],
12325
+ "returns": "this"
12326
+ },
12279
12327
  "afterInitialize": {
12280
12328
  "description": "Called immediately after the assistant is constructed. Synchronously loads the system prompt, tools, and hooks, then binds hooks as event listeners so every emitted event automatically invokes its corresponding hook.",
12281
12329
  "parameters": {},
@@ -20191,6 +20239,32 @@ export const introspectionData = [
20191
20239
  }
20192
20240
  ]
20193
20241
  },
20242
+ "isSymlink": {
20243
+ "description": "Checks if a path is a symbolic link.",
20244
+ "parameters": {
20245
+ "path": {
20246
+ "type": "string",
20247
+ "description": "The path to check"
20248
+ }
20249
+ },
20250
+ "required": [
20251
+ "path"
20252
+ ],
20253
+ "returns": "boolean"
20254
+ },
20255
+ "realpath": {
20256
+ "description": "Resolves a symlink to its real path. Returns the resolved path as-is if not a symlink.",
20257
+ "parameters": {
20258
+ "path": {
20259
+ "type": "string",
20260
+ "description": "The path to resolve"
20261
+ }
20262
+ },
20263
+ "required": [
20264
+ "path"
20265
+ ],
20266
+ "returns": "string"
20267
+ },
20194
20268
  "stat": {
20195
20269
  "description": "Synchronously returns the stat object for a file or directory.",
20196
20270
  "parameters": {
@@ -26081,6 +26155,10 @@ export const introspectionData = [
26081
26155
  "maxTokens": {
26082
26156
  "type": "number",
26083
26157
  "description": ""
26158
+ },
26159
+ "schema": {
26160
+ "type": "z.ZodType",
26161
+ "description": "When provided, enables OpenAI Structured Outputs. The model is constrained to return JSON matching this Zod schema. The return value of ask() will be the parsed object instead of a raw string."
26084
26162
  }
26085
26163
  }
26086
26164
  }
@@ -26198,6 +26276,21 @@ export const introspectionData = [
26198
26276
  "description": "Event emitted by Conversation",
26199
26277
  "arguments": {}
26200
26278
  },
26279
+ "toolError": {
26280
+ "name": "toolError",
26281
+ "description": "Event emitted by Conversation",
26282
+ "arguments": {}
26283
+ },
26284
+ "toolCall": {
26285
+ "name": "toolCall",
26286
+ "description": "Event emitted by Conversation",
26287
+ "arguments": {}
26288
+ },
26289
+ "toolResult": {
26290
+ "name": "toolResult",
26291
+ "description": "Event emitted by Conversation",
26292
+ "arguments": {}
26293
+ },
26201
26294
  "turnStart": {
26202
26295
  "name": "turnStart",
26203
26296
  "description": "Event emitted by Conversation",
@@ -26233,21 +26326,6 @@ export const introspectionData = [
26233
26326
  "description": "Event emitted by Conversation",
26234
26327
  "arguments": {}
26235
26328
  },
26236
- "toolError": {
26237
- "name": "toolError",
26238
- "description": "Event emitted by Conversation",
26239
- "arguments": {}
26240
- },
26241
- "toolCall": {
26242
- "name": "toolCall",
26243
- "description": "Event emitted by Conversation",
26244
- "arguments": {}
26245
- },
26246
- "toolResult": {
26247
- "name": "toolResult",
26248
- "description": "Event emitted by Conversation",
26249
- "arguments": {}
26250
- },
26251
26329
  "toolCallsEnd": {
26252
26330
  "name": "toolCallsEnd",
26253
26331
  "description": "Event emitted by Conversation",
@@ -26663,6 +26741,24 @@ export const introspectionData = [
26663
26741
  "shortcut": "features.assistant",
26664
26742
  "className": "Assistant",
26665
26743
  "methods": {
26744
+ "intercept": {
26745
+ "description": "Register an interceptor at a given point in the pipeline.",
26746
+ "parameters": {
26747
+ "point": {
26748
+ "type": "K",
26749
+ "description": "The interception point"
26750
+ },
26751
+ "fn": {
26752
+ "type": "InterceptorFn<InterceptorPoints[K]>",
26753
+ "description": "Middleware function receiving (ctx, next)"
26754
+ }
26755
+ },
26756
+ "required": [
26757
+ "point",
26758
+ "fn"
26759
+ ],
26760
+ "returns": "this"
26761
+ },
26666
26762
  "afterInitialize": {
26667
26763
  "description": "Called immediately after the assistant is constructed. Synchronously loads the system prompt, tools, and hooks, then binds hooks as event listeners so every emitted event automatically invokes its corresponding hook.",
26668
26764
  "parameters": {},