@kjerneverk/execution-openai 1.0.5-dev.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.
Files changed (50) hide show
  1. package/.kodrdriv-test-cache.json +6 -0
  2. package/LICENSE +18 -0
  3. package/README.md +80 -0
  4. package/dist/index.d.ts +85 -0
  5. package/dist/index.js +103 -0
  6. package/dist/index.js.map +1 -0
  7. package/output/kodrdriv/.kodrdriv-parallel-context.json +589 -0
  8. package/output/kodrdriv/260110-1751-release-notes.md +39 -0
  9. package/output/kodrdriv/260112-2207-commit-message.md +1 -0
  10. package/output/kodrdriv/260112-2208-release-notes.md +36 -0
  11. package/output/kodrdriv/260112-2341-commit-message.md +1 -0
  12. package/output/kodrdriv/260113-0029-commit-message.md +1 -0
  13. package/output/kodrdriv/260113-0030-release-notes.md +5 -0
  14. package/output/kodrdriv/260114-0656-commit-message.md +6 -0
  15. package/output/kodrdriv/260115-0616-commit-message.md +1 -0
  16. package/output/kodrdriv/260115-0739-commit-message.md +1 -0
  17. package/output/kodrdriv/260126-0852-commit-message.md +1 -0
  18. package/output/kodrdriv/260126-0853-release-notes.md +47 -0
  19. package/output/kodrdriv/260126-0854-release-notes.md +50 -0
  20. package/output/kodrdriv/260128-0929-commit-message.md +1 -0
  21. package/output/kodrdriv/260128-0929-release-notes.md +24 -0
  22. package/output/kodrdriv/260128-0959-commit-message.md +6 -0
  23. package/output/kodrdriv/260128-1127-commit-message.md +1 -0
  24. package/output/kodrdriv/260128-1127-release-notes.md +30 -0
  25. package/output/kodrdriv/260130-1639-commit-message.md +5 -0
  26. package/output/kodrdriv/260130-1652-commit-message.md +1 -0
  27. package/output/kodrdriv/260130-1652-release-notes.md +27 -0
  28. package/output/kodrdriv/RELEASE_NOTES.md +25 -0
  29. package/output/kodrdriv/RELEASE_TITLE.md +1 -0
  30. package/output/kodrdriv/agentic-reflection-commit-2026-01-13T06-07-12-251Z.md +97 -0
  31. package/output/kodrdriv/agentic-reflection-commit-2026-01-13T07-41-08-151Z.md +97 -0
  32. package/output/kodrdriv/agentic-reflection-commit-2026-01-13T08-29-26-449Z.md +97 -0
  33. package/output/kodrdriv/agentic-reflection-commit-2026-01-14T14-56-03-314Z.md +102 -0
  34. package/output/kodrdriv/agentic-reflection-commit-2026-01-15T14-16-42-406Z.md +97 -0
  35. package/output/kodrdriv/agentic-reflection-commit-2026-01-15T15-39-56-545Z.md +114 -0
  36. package/output/kodrdriv/agentic-reflection-commit-2026-01-26T16-52-42-503Z.md +152 -0
  37. package/output/kodrdriv/agentic-reflection-commit-2026-01-28T17-59-30-913Z.md +204 -0
  38. package/output/kodrdriv/agentic-reflection-commit-2026-01-31T00-39-30-443Z.md +245 -0
  39. package/output/kodrdriv/agentic-reflection-commit-2026-01-31T00-52-07-165Z.md +152 -0
  40. package/output/kodrdriv/agentic-reflection-release-2026-01-11T01-51-19-115Z.md +277 -0
  41. package/output/kodrdriv/agentic-reflection-release-2026-01-13T06-08-15-507Z.md +289 -0
  42. package/output/kodrdriv/agentic-reflection-release-2026-01-13T08-30-05-728Z.md +312 -0
  43. package/output/kodrdriv/agentic-reflection-release-2026-01-26T16-53-34-128Z.md +417 -0
  44. package/output/kodrdriv/agentic-reflection-release-2026-01-26T16-53-55-634Z.md +391 -0
  45. package/output/kodrdriv/agentic-reflection-release-2026-01-26T16-54-13-700Z.md +456 -0
  46. package/output/kodrdriv/agentic-reflection-release-2026-01-26T16-54-22-655Z.md +496 -0
  47. package/output/kodrdriv/agentic-reflection-release-2026-01-26T16-54-32-261Z.md +490 -0
  48. package/output/kodrdriv/agentic-reflection-release-2026-01-31T00-52-29-053Z.md +334 -0
  49. package/package.json +58 -0
  50. package/package.json~ +57 -0
@@ -0,0 +1,152 @@
1
+ # Agentic Workflow - Self-Reflection Report
2
+
3
+ Generated: 2026-01-31T00:52:07.165Z
4
+
5
+ ## Execution Summary
6
+
7
+ - **Iterations**: 3
8
+ - **Tool Calls**: 5
9
+ - **Unique Tools**: 5
10
+
11
+ ## Tool Effectiveness Analysis
12
+
13
+ | Tool | Calls | Success | Failures | Success Rate | Avg Duration |
14
+ |------|-------|---------|----------|--------------|--------------|
15
+ | get_file_content | 1 | 1 | 0 | 100.0% | 1ms |
16
+ | get_file_modification_times | 1 | 1 | 0 | 100.0% | 0ms |
17
+ | group_files_by_concern | 1 | 1 | 0 | 100.0% | 1ms |
18
+ | get_recent_commits | 1 | 1 | 0 | 100.0% | 19ms |
19
+ | get_file_history | 1 | 1 | 0 | 100.0% | 20ms |
20
+
21
+ ### Tool Performance Insights
22
+
23
+ **Most Frequently Used:**
24
+ - get_file_content: 1 calls
25
+ - get_file_modification_times: 1 calls
26
+ - group_files_by_concern: 1 calls
27
+
28
+ ## Recommendations for Improvement
29
+
30
+ - **Underutilized Tools**: Many tools were called only once. Consider whether all tools are necessary or if the agent needs better guidance on when to use them.
31
+
32
+ ## Detailed Execution Timeline
33
+
34
+ | Time | Iteration | Tool | Result | Duration |
35
+ |------|-----------|------|--------|----------|
36
+ | 4:52:00 PM | 1 | get_file_content | ✅ Success | 1ms |
37
+ | 4:52:00 PM | 1 | get_file_modification_times | ✅ Success | 0ms |
38
+ | 4:52:00 PM | 1 | group_files_by_concern | ✅ Success | 1ms |
39
+ | 4:52:00 PM | 1 | get_recent_commits | ✅ Success | 19ms |
40
+ | 4:52:03 PM | 2 | get_file_history | ✅ Success | 20ms |
41
+
42
+ ## Conversation History
43
+
44
+ <details>
45
+ <summary>Click to expand full agentic interaction</summary>
46
+
47
+ ```json
48
+ [
49
+ {
50
+ "role": "system",
51
+ "content": "You are a professional software engineer writing commit messages for your team.\n\n## Available Tools\n\nYou have access to tools to investigate the changes:\n- `get_file_content` - Read file contents or diffs for specific files\n- `get_file_modification_times` - See when files were modified relative to each other\n- `group_files_by_concern` - Understand how files relate by type/purpose\n- `get_recent_commits` - Get recent commit history to avoid duplicates\n- `get_file_history` - Understand how code evolved\n- `get_file_dependencies` - Assess impact of changes\n- `get_related_tests` - Find related test files\n- `search_codebase` - Search for usage patterns\n\nUse these tools to investigate the changes rather than asking for information upfront.\n\n## Your Task\n\nAnalyze the staged changes and determine the best way to commit them. Your primary goal is to create **meaningful, atomic commits** that each represent a single logical change.\n\n**CRITICAL**: When there are many changed files, especially after a long work session (multiple hours), you should almost always split them into multiple commits. A single commit with 10+ files usually indicates multiple distinct changes that should be separated.\n\nThink about:\n- What distinct features, fixes, or improvements are represented?\n- Are there natural groupings by functionality, module, or purpose?\n- When were files modified relative to each other?\n- What should reviewers focus on in each commit?\n\n## Investigation Strategy\n\nFor any non-trivial set of changes, gather multiple signals to understand how to group commits:\n\n1. **Check file modification times** using `get_file_modification_times`\n - This reveals *when* files were changed relative to each other\n - Files modified close together *may* be part of the same logical change\n - Large temporal gaps *can* indicate separate work sessions\n - Note: temporal proximity is one signal, not a guarantee of relatedness\n\n2. **Understand logical relationships** using `group_files_by_concern`\n - Groups by module, type (tests, docs, source), and directory structure\n - Reveals which files are functionally related regardless of when they were modified\n\n3. **Cross-reference both signals** to make informed decisions:\n - Files modified together AND logically related → strong candidate for same commit\n - Files modified apart BUT logically related → might still belong together\n - Files modified together BUT logically unrelated → consider splitting\n - Use your judgment - neither signal is definitive on its own\n\n4. **Investigate further** as needed:\n - get_file_content - see full context when diffs are unclear\n - get_file_history - understand how code evolved\n - get_file_dependencies - assess impact of changes\n - get_recent_commits - avoid duplicate messages\n - get_related_tests - understand behavior changes\n - search_codebase - find usage patterns\n\n## When to Split Commits\n\n**Prefer multiple commits when:**\n- Changes span multiple hours of work (check modification times!)\n- Different logical features or fixes are included\n- Test changes could be separated from production code changes\n- Documentation updates are unrelated to code changes\n- Refactoring is mixed with feature work\n- Configuration changes are mixed with implementation changes\n- Files in different modules/packages are changed for different reasons\n\n**Keep as one commit when:**\n- All changes are part of a single, cohesive feature\n- Files were modified together in a focused work session\n- Test changes directly test the production code changes\n- The changes tell a single coherent story\n\n**Default bias**: When in doubt about whether to split, **prefer splitting**. It's better to have too many focused commits than too few bloated ones. A good commit should be understandable and reviewable in isolation.\n\n## Important Context Guidelines\n\nIf additional context is provided (from context files or other sources), use your judgment:\n- If the context is relevant to these specific changes, incorporate it\n- If the context describes unrelated changes or other packages, ignore it\n- Don't force connections between unrelated information\n- Focus on accurately describing what actually changed\n\n## Writing Style\n\nWrite naturally and directly:\n- Use plain language, not corporate speak\n- Be specific and concrete\n- Avoid buzzwords and jargon\n- No emojis or excessive punctuation\n- No phrases like \"this commit\" or \"this PR\"\n- No meta-commentary about the commit itself\n\nFollow conventional commit format when appropriate (feat:, fix:, refactor:, docs:, test:, chore:), but prioritize clarity over formality.\n\n## Output Format\n\nWhen ready, format your response as:\n\nCOMMIT_MESSAGE:\n[Your commit message here - only for the FIRST group of changes if splitting]\n\nIf changes should be split into multiple commits (which is often the case with large changesets):\n\nSUGGESTED_SPLITS:\nSplit 1:\nFiles: [list of files]\nRationale: [why these belong together - mention temporal clustering and/or logical relationship]\nMessage: [commit message for this split]\n\nSplit 2:\nFiles: [list of files]\nRationale: [why these belong together]\nMessage: [commit message for this split]\n\nSplit 3:\n...\n\nOutput only the commit message and splits. No conversational remarks or follow-up offers."
52
+ },
53
+ {
54
+ "role": "user",
55
+ "content": "I have staged changes that need a commit message.\n\nChanged files (1):\n - package.json\n\n## Your Analysis Task\n\nUse your tools to investigate the changes:\n1. Use `get_file_content` to read the actual changes in the files\n2. Use `get_file_modification_times` to see when files were modified relative to each other\n3. Use `group_files_by_concern` to understand how files relate by type/purpose\n4. Use `get_recent_commits` to check recent commit history and avoid duplicates\n5. Cross-reference temporal proximity and logical relatedness to determine the best commit structure\n\nConsider:\n- What distinct features, fixes, or improvements are included?\n- Are files that were modified together also logically related?\n- Would separate commits make the history more understandable?\n\nIf changes represent multiple logical concerns, suggest splits.\n\nStart by reading the file contents to understand what actually changed."
56
+ },
57
+ {
58
+ "role": "assistant",
59
+ "content": null,
60
+ "tool_calls": [
61
+ {
62
+ "id": "call_sGlhgqIlsrxJEiJu1sf2MyvN",
63
+ "type": "function",
64
+ "function": {
65
+ "name": "get_file_content",
66
+ "arguments": "{\"filePath\": \"package.json\", \"includeLineNumbers\": false}"
67
+ }
68
+ },
69
+ {
70
+ "id": "call_pHdDzj6bu54B6ZwuflVxuzzJ",
71
+ "type": "function",
72
+ "function": {
73
+ "name": "get_file_modification_times",
74
+ "arguments": "{\"filePaths\": [\"package.json\"]}"
75
+ }
76
+ },
77
+ {
78
+ "id": "call_BDdWXbtWgssNpPtUBQJgxmlc",
79
+ "type": "function",
80
+ "function": {
81
+ "name": "group_files_by_concern",
82
+ "arguments": "{\"filePaths\": [\"package.json\"]}"
83
+ }
84
+ },
85
+ {
86
+ "id": "call_6bsWIl4Woi4VMWC4Np6Vogj6",
87
+ "type": "function",
88
+ "function": {
89
+ "name": "get_recent_commits",
90
+ "arguments": "{\"filePaths\": [\"package.json\"], \"since\": \"1 week ago\", \"limit\": 5}"
91
+ }
92
+ }
93
+ ]
94
+ },
95
+ {
96
+ "role": "tool",
97
+ "tool_call_id": "call_sGlhgqIlsrxJEiJu1sf2MyvN",
98
+ "content": "{\n \"name\": \"@riotprompt/execution-openai\",\n \"version\": \"1.0.4\",\n \"description\": \"OpenAI provider for execution - implements Provider interface\",\n \"type\": \"module\",\n \"main\": \"./dist/index.js\",\n \"types\": \"./dist/index.d.ts\",\n \"exports\": {\n \".\": {\n \"types\": \"./dist/index.d.ts\",\n \"import\": \"./dist/index.js\"\n }\n },\n \"engines\": {\n \"node\": \">=24.0.0\"\n },\n \"scripts\": {\n \"clean\": \"rm -rf dist\",\n \"build\": \"vite build\",\n \"test\": \"vitest run --coverage\",\n \"test:coverage\": \"vitest run --coverage\",\n \"lint\": \"eslint src\",\n \"precommit\": \"npm run build && npm run lint && npm run test\",\n \"prepublishOnly\": \"npm run clean && npm run build\"\n },\n \"keywords\": [\n \"llm\",\n \"openai\",\n \"gpt\",\n \"execution\",\n \"provider\"\n ],\n \"author\": \"Tim O'Brien <tobrien@discursive.com>\",\n \"license\": \"Apache-2.0\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"https://github.com/kjerneverk/execution-openai\"\n },\n \"dependencies\": {\n \"@utilarium/offrecord\": \"^0.0.3\",\n \"@utilarium/spotclean\": \"^0.0.4\",\n \"openai\": \"^6.16.0\",\n \"tiktoken\": \"^1.0.21\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^25.0.6\",\n \"@typescript-eslint/eslint-plugin\": \"^8.33.1\",\n \"@typescript-eslint/parser\": \"^8.33.1\",\n \"@vitest/coverage-v8\": \"^4.0.18\",\n \"ajv\": \"^8.17.1\",\n \"eslint\": \"^9.28.0\",\n \"globals\": \"^17.2.0\",\n \"typescript\": \"^5.8.3\",\n \"vite\": \"^7.0.4\",\n \"vite-plugin-dts\": \"^4.5.4\",\n \"vitest\": \"^4.0.18\"\n }\n}\n",
99
+ "name": "get_file_content"
100
+ },
101
+ {
102
+ "role": "tool",
103
+ "tool_call_id": "call_pHdDzj6bu54B6ZwuflVxuzzJ",
104
+ "content": "## File Modification Times (sorted oldest to newest)\n\n2026-01-31 00:51:58 package.json\n\n\n## Temporal Clusters (files modified within 10 minutes of each other)\n\nAll 1 files were modified in a single work session.\n",
105
+ "name": "get_file_modification_times"
106
+ },
107
+ {
108
+ "role": "tool",
109
+ "tool_call_id": "call_BDdWXbtWgssNpPtUBQJgxmlc",
110
+ "content": "dependencies (1 files):\n - package.json\n\nSuggestion: All files appear to be related and should be in a single commit.",
111
+ "name": "group_files_by_concern"
112
+ },
113
+ {
114
+ "role": "tool",
115
+ "tool_call_id": "call_6bsWIl4Woi4VMWC4Np6Vogj6",
116
+ "content": "a9e689a - feat(openai): inline execution types and harden secret/error sanitization (Tim O'Brien, 13 minutes ago)\nd51cb41 - chore: bump to 1.0.4-dev.0 (Tim O'Brien, 2 days ago)\na6c4d89 - feat(openai): add model-aware provider and sanitize OpenAI secrets (Tim O'Brien, 2 days ago)\n5a30ec6 - chore: bump to 1.0.2-dev.0 (#15) (Tim O'Brien, 2 days ago)\nb827fd9 - fix: add npm tag detection for prerelease versions in publish workflow (#14) (Tim O'Brien, 2 days ago)\n",
117
+ "name": "get_recent_commits"
118
+ },
119
+ {
120
+ "role": "assistant",
121
+ "content": null,
122
+ "tool_calls": [
123
+ {
124
+ "id": "call_LlYdALMU1AGKop7G9UfQAH0Q",
125
+ "type": "function",
126
+ "function": {
127
+ "name": "get_file_history",
128
+ "arguments": "{\"filePaths\":[\"package.json\"],\"limit\":5,\"format\":\"detailed\"}"
129
+ }
130
+ }
131
+ ]
132
+ },
133
+ {
134
+ "role": "tool",
135
+ "tool_call_id": "call_LlYdALMU1AGKop7G9UfQAH0Q",
136
+ "content": "a9e689aa6fbdce93cab5814a150b39590b112281\nTim O'Brien (tobrien@discursive.com)\nFri Jan 30 16:39:30 2026 -0800\nfeat(openai): inline execution types and harden secret/error sanitization\n\n- Register/validate OpenAI key patterns and sanitize provider errors via offrecord/spotclean\n- Vendor minimal `execution` types to keep build independent\n- Update Vite library build externals and package deps to match new runtime requirements\n\n---\nd51cb414501d896e020f023beb3e20f285187e60\nTim O'Brien (tobrien@discursive.com)\nWed Jan 28 11:29:00 2026 -0800\nchore: bump to 1.0.4-dev.0\n\n\n---\na6c4d897b4a8d8bfdf417633ee4e1fc9ff466d96\nTim O'Brien (tobrien@discursive.com)\nWed Jan 28 11:27:51 2026 -0800\nfeat(openai): add model-aware provider and sanitize OpenAI secrets\n\n- Implement OpenAIProvider with model selection via request/options and supportsModel checks\n- Register OpenAI key patterns and validate API key format before client creation\n-... (#16)\n\n* chore: bump to 1.0.2-dev.0\n\n* chore: bump to 1.0.3-dev.0\n\n* feat(openai): add model-aware provider and sanitize OpenAI secrets\n\n- Implement OpenAIProvider with model selection via request/options and supportsModel checks\n- Register OpenAI key patterns and validate API key format before client creation\n- Sanitize/redact secrets in thrown errors using offrecord/spotclean\n- Add offrecord/spotclean dependencies to package.json\n---\n5a30ec636ed7c9d3118d9ce5d115d632de67f4b9\nTim O'Brien (tobrien@discursive.com)\nWed Jan 28 09:45:18 2026 -0800\nchore: bump to 1.0.2-dev.0 (#15)\n\n\n---\nb827fd921b95e0e3a0d8718c5c5c219f39390b90\nTim O'Brien (tobrien@discursive.com)\nWed Jan 28 09:29:35 2026 -0800\nfix: add npm tag detection for prerelease versions in publish workflow (#14)\n\n* chore: bump to 1.0.0-dev.0\n\n* Updating version\n\n* fix: add targeted ajv override for vite-plugin-dts\n\n* fix: add ajv@^8 as explicit devDependency to resolve vite-plugin-dts conflict\n\n* fix: add npm tag detection for prerelease versions in publish workflow\n---\n",
137
+ "name": "get_file_history"
138
+ },
139
+ {
140
+ "role": "assistant",
141
+ "content": "COMMIT_MESSAGE:\nchore: release 1.0.4"
142
+ }
143
+ ]
144
+ ```
145
+
146
+ </details>
147
+
148
+ ## Generated Commit Message
149
+
150
+ ```
151
+ chore: release 1.0.4
152
+ ```
@@ -0,0 +1,277 @@
1
+ # Agentic Workflow - Self-Reflection Report
2
+
3
+ Generated: 2026-01-11T01:51:19.115Z
4
+
5
+ ## Execution Summary
6
+
7
+ - **Iterations**: 4
8
+ - **Tool Calls**: 10
9
+ - **Unique Tools**: 7
10
+
11
+ ## Tool Effectiveness Analysis
12
+
13
+ | Tool | Calls | Success | Failures | Success Rate | Avg Duration |
14
+ |------|-------|---------|----------|--------------|--------------|
15
+ | get_file_content | 4 | 4 | 0 | 100.0% | 1ms |
16
+ | get_release_stats | 1 | 1 | 0 | 100.0% | 41ms |
17
+ | get_breaking_changes | 1 | 1 | 0 | 100.0% | 24ms |
18
+ | analyze_commit_patterns | 1 | 1 | 0 | 100.0% | 9ms |
19
+ | get_related_tests | 1 | 1 | 0 | 100.0% | 2ms |
20
+ | get_file_dependencies | 1 | 1 | 0 | 100.0% | 19ms |
21
+ | get_file_history | 1 | 1 | 0 | 100.0% | 14ms |
22
+
23
+ ### Tool Performance Insights
24
+
25
+ **Most Frequently Used:**
26
+ - get_release_stats: 1 calls
27
+ - get_breaking_changes: 1 calls
28
+ - analyze_commit_patterns: 1 calls
29
+
30
+ ## Recommendations for Improvement
31
+
32
+ - **Underutilized Tools**: Many tools were called only once. Consider whether all tools are necessary or if the agent needs better guidance on when to use them.
33
+
34
+ ## Detailed Execution Timeline
35
+
36
+ | Time | Iteration | Tool | Result | Duration |
37
+ |------|-----------|------|--------|----------|
38
+ | 5:50:29 PM | 1 | get_release_stats | ✅ Success | 41ms |
39
+ | 5:50:29 PM | 1 | get_breaking_changes | ✅ Success | 24ms |
40
+ | 5:50:29 PM | 1 | analyze_commit_patterns | ✅ Success | 9ms |
41
+ | 5:50:29 PM | 1 | get_file_content | ✅ Success | 0ms |
42
+ | 5:50:29 PM | 1 | get_file_content | ✅ Success | 0ms |
43
+ | 5:50:29 PM | 1 | get_file_content | ✅ Success | 1ms |
44
+ | 5:50:41 PM | 2 | get_file_content | ✅ Success | 1ms |
45
+ | 5:50:41 PM | 2 | get_related_tests | ✅ Success | 2ms |
46
+ | 5:50:41 PM | 2 | get_file_dependencies | ✅ Success | 19ms |
47
+ | 5:50:51 PM | 3 | get_file_history | ✅ Success | 14ms |
48
+
49
+ ## Conversation History
50
+
51
+ <details>
52
+ <summary>Click to expand full agentic interaction</summary>
53
+
54
+ ```json
55
+ [
56
+ {
57
+ "role": "system",
58
+ "content": "You are a professional software engineer writing release notes for your team and users.\n\n## Available Tools\n\n### General\n\n**get_file_history**\nGet git commit history for one or more files to understand their evolution and past changes\n\nParameters:\n- `filePaths` (required): Array of file paths to get history for\n- `limit`: Maximum number of commits to return (default: 10)\n- `format`: Output format: \"summary\" for brief or \"detailed\" for full messages\n\n**When to use:** Get git commit history for one or more files to understand their evolution and past changes\n\n---\n\n**get_file_content**\nGet the complete current content of a file to understand context around changes. Returns a message if the file does not exist (e.g., if it was deleted).\n\nParameters:\n- `filePath` (required): Path to the file\n- `includeLineNumbers`: Include line numbers in output (default: false)\n\n**When to use:** Get the complete current content of a file to understand context around changes. Returns a message if the file does not exist (e.g., if it was deleted).\n\n---\n\n**search_codebase**\nSearch for code patterns, function names, or text across the codebase using git grep\n\nParameters:\n- `query` (required): Search pattern (can be plain text or regex)\n- `fileTypes`: Limit search to specific file extensions (e.g., [\"ts\", \"js\"])\n- `contextLines`: Number of context lines to show around matches (default: 2)\n\n**When to use:** Search for code patterns, function names, or text across the codebase using git grep\n\n---\n\n**get_related_tests**\nFind test files related to production files to understand what the code is supposed to do\n\nParameters:\n- `filePaths` (required): Production file paths\n\n**When to use:** Find test files related to production files to understand what the code is supposed to do\n\n---\n\n**get_file_dependencies**\nFind which files import or depend on the changed files to assess change impact\n\nParameters:\n- `filePaths` (required): Files to analyze dependencies for\n\n**When to use:** Find which files import or depend on the changed files to assess change impact\n\n---\n\n**analyze_diff_section**\nGet expanded context around specific lines in a file to better understand changes\n\nParameters:\n- `filePath` (required): File containing the section to analyze\n- `startLine` (required): Starting line number\n- `endLine` (required): Ending line number\n- `contextLines`: Number of additional context lines to show before and after (default: 10)\n\n**When to use:** Get expanded context around specific lines in a file to better understand changes\n\n---\n\n**get_recent_commits**\nGet recent commits that modified the same files to understand recent work in this area\n\nParameters:\n- `filePaths` (required): Files to check for recent commits\n- `since`: Time period to look back (e.g., \"1 week ago\", \"2 days ago\")\n- `limit`: Maximum number of commits to return (default: 5)\n\n**When to use:** Get recent commits that modified the same files to understand recent work in this area\n\n---\n\n**group_files_by_concern**\nAnalyze changed files and suggest logical groupings that might represent separate concerns\n\nParameters:\n- `filePaths` (required): All changed files to analyze\n\n**When to use:** Analyze changed files and suggest logical groupings that might represent separate concerns\n\n---\n\n### Release Analysis\n\n**get_tag_history** _(cheap)_\nGet the history of previous release tags to understand release patterns and versioning\n\nParameters:\n- `limit`: Number of recent tags to retrieve (default: 10)\n- `pattern`: Filter tags by pattern (e.g., \"v*\" for version tags)\n\n**When to use:** Get the history of previous release tags to understand release patterns and versioning\n\n**Examples:**\n- Check recent version tags: `get_tag_history({\"limit\":5,\"pattern\":\"v*\"})`\n\n---\n\n**compare_previous_release** _(moderate)_\nCompare this release with a previous release to understand what changed between versions\n\nParameters:\n- `previousTag` (required): Previous release tag to compare against\n- `currentRef`: Current reference (default: HEAD)\n- `statsOnly`: Return only statistics, not full diff (default: true)\n\n**When to use:** Compare this release with a previous release to understand what changed between versions\n\n**Examples:**\n- Compare with last release: `compare_previous_release({\"previousTag\":\"v1.0.0\",\"currentRef\":\"HEAD\"})`\n\n---\n\n**get_release_stats** _(moderate)_\nGet comprehensive statistics about the release including contributors, file changes, and commit patterns\n\nParameters:\n- `fromRef` (required): Starting reference for the release range\n- `toRef`: Ending reference for the release range (default: HEAD)\n\n**When to use:** Get comprehensive statistics about the release including contributors, file changes, and commit patterns\n\n**Examples:**\n- Get release overview: `get_release_stats({\"fromRef\":\"v1.0.0\",\"toRef\":\"HEAD\"})`\n\n---\n\n**get_breaking_changes** _(expensive)_\nSearch for potential breaking changes by looking for specific patterns in commits and diffs\n\nParameters:\n- `fromRef` (required): Starting reference for the release range\n- `toRef`: Ending reference for the release range (default: HEAD)\n\n**When to use:** Search for potential breaking changes by looking for specific patterns in commits and diffs\n\n**Examples:**\n- Check for breaking changes: `get_breaking_changes({\"fromRef\":\"v1.0.0\",\"toRef\":\"HEAD\"})`\n\n---\n\n**analyze_commit_patterns** _(cheap)_\nAnalyze commit messages to identify patterns and themes in the release\n\nParameters:\n- `fromRef` (required): Starting reference for the release range\n- `toRef`: Ending reference for the release range (default: HEAD)\n\n**When to use:** Analyze commit messages to identify patterns and themes in the release\n\n**Examples:**\n- Find commit themes: `analyze_commit_patterns({\"fromRef\":\"v1.0.0\",\"toRef\":\"HEAD\"})`\n\n---\n\n\n\n## Your Task\n\nWrite release notes that clearly explain what's in this release and why it matters. Your notes should help users and developers understand what changed without needing to read every commit.\n\nFocus on:\n- What problems does this release solve?\n- What new capabilities does it add?\n- What's the impact on users and developers?\n- Are there breaking changes or important considerations?\n\nUse the available tools to investigate the changes. The more you understand, the better your notes will be.\n\n**Important**: If additional context is provided (from context files or other sources), use your judgment:\n- If the context is relevant to this specific package/release, incorporate it appropriately\n- If the context describes changes in other packages or unrelated work, ignore it\n- Don't fabricate connections between this package and unrelated context\n- Be honest about what changed - only mention what actually happened in this release\n- Context is supplemental information, not a requirement to include\n\n## Investigation Approach\n\nUse tools based on what you need to know:\n\n**Context:**\n- get_tag_history - understand release patterns\n- get_release_stats - quantify scope\n- compare_previous_release - see how this compares\n\n**Understanding:**\n- group_files_by_concern - identify themes\n- analyze_commit_patterns - detect patterns\n- get_file_content - see full context\n- analyze_diff_section - expand unclear changes\n- get_file_history - understand evolution\n\n**Impact:**\n- get_file_dependencies - assess reach\n- search_codebase - find usage patterns\n- get_related_tests - understand behavior changes\n- get_breaking_changes - identify breaking changes (always use)\n\n## Writing Style\n\nWrite naturally and directly:\n- Use plain language that users can understand\n- Be specific about what changed and why\n- Avoid marketing speak and buzzwords\n- No emojis or excessive punctuation\n- No phrases like \"we're excited to announce\"\n- No meta-commentary about the release itself\n- Focus on facts and implications, not enthusiasm\n\nStructure your notes logically:\n- Start with the most important changes\n- Group related changes together\n- Explain breaking changes clearly\n- Include practical examples when helpful\n\n## Output Format\n\nWhen ready, format your response as JSON:\n\nRELEASE_NOTES:\n{\n \"title\": \"Clear, factual title describing the main changes\",\n \"body\": \"Detailed release notes in Markdown format\"\n}\n\nOutput only the JSON. No conversational remarks or follow-up offers."
59
+ },
60
+ {
61
+ "role": "user",
62
+ "content": "I need comprehensive release notes for changes from main to HEAD.\n\n## Commit Log\ncommit 43f7d7086e7fe112c171b0a0595251d47481f7d8\nAuthor: Tim O'Brien <tobrien@discursive.com>\nDate: Sat Jan 10 13:19:17 2026 -0800\n\n Updated and separated tests\n\ncommit 7948ae0dfcf8860fcbcc9965dff01f047e52a5c2\nAuthor: Tim O'Brien <tobrien@discursive.com>\nDate: Sat Jan 10 11:22:13 2026 -0800\n\n 0.0.2-dev.0\n\n\n## Diff Summary\ndiff --git a/.kodrdriv-test-cache.json b/.kodrdriv-test-cache.json\nindex a37483e..3aa4aad 100644\n--- a/.kodrdriv-test-cache.json\n+++ b/.kodrdriv-test-cache.json\n@@ -1,6 +1,6 @@\n {\n \"/Users/tobrien/gitw/kjerneverk/execution-openai\": {\n- \"lastTestRun\": 1768072530749,\n- \"lastCommitHash\": \"unknown\"\n+ \"lastTestRun\": 1768074156142,\n+ \"lastCommitHash\": \"7948ae0dfcf8860fcbcc9965dff01f047e52a5c2\"\n }\n }\n\\ndiff --git a/package.json b/package.json\nindex ab8bd47..bc49253 100644\n--- a/package.json\n+++ b/package.json\n@@ -1,6 +1,6 @@\n {\n \"name\": \"@riotprompt/execution-openai\",\n- \"version\": \"0.0.1\",\n+ \"version\": \"0.0.2\",\n \"description\": \"OpenAI provider for execution - implements Provider interface\",\n \"type\": \"module\",\n \"main\": \"./dist/index.cjs\",\n@@ -14,9 +14,13 @@\n }\n },\n \"scripts\": {\n+ \"clean\": \"rm -rf dist\",\n \"build\": \"vite build\",\n- \"test\": \"vitest run\",\n- \"lint\": \"eslint src\"\n+ \"test\": \"vitest run --coverage\",\n+ \"test:coverage\": \"vitest run --coverage\",\n+ \"lint\": \"eslint src\",\n+ \"precommit\": \"npm run lint && npm run test\",\n+ \"prepublishOnly\": \"npm run clean && npm run build\"\n },\n \"keywords\": [\n \"llm\",\n@@ -29,7 +33,7 @@\n \"license\": \"Apache-2.0\",\n \"repository\": {\n \"type\": \"git\",\n- \"url\": \"git+https://github.com/kjerneverk/execution-openai\"\n+ \"url\": \"https://github.com/kjerneverk/execution-openai\"\n },\n \"dependencies\": {\n \"openai\": \"^4.103.0\",\n@@ -39,6 +43,7 @@\n \"@types/node\": \"^25.0.6\",\n \"@typescript-eslint/eslint-plugin\": \"^8.33.1\",\n \"@typescript-eslint/parser\": \"^8.33.1\",\n+ \"@vitest/coverage-v8\": \"^3.2.4\",\n \"eslint\": \"^9.28.0\",\n \"globals\": \"^16.2.0\",\n \"typescript\": \"^5.8.3\",\ndiff --git a/src/index.test.ts b/tests/index.test.ts\nsimilarity index 99%\nrename from src/index.test.ts\nrename to tests/index.test.ts\nindex f80ddc9..5b0e61a 100644\n--- a/src/index.test.ts\n+++ b/tests/index.test.ts\n@@ -12,7 +12,7 @@ import {\n type ExecutionOptions,\n type ProviderResponse,\n type Provider,\n-} from './index.js';\n+} from '../src/index.js';\n \n describe('OpenAIProvider', () => {\n let provider: OpenAIProvider;\ndiff --git a/vitest.config.ts b/vitest.config.ts\nindex e8ae80a..c6f4053 100644\n--- a/vitest.config.ts\n+++ b/vitest.config.ts\n@@ -2,13 +2,20 @@ import { defineConfig } from \"vitest/config\";\n \n export default defineConfig({\n test: {\n- include: [\"src/**/*.test.ts\", \"tests/**/*.test.ts\"],\n+ include: [\"tests/**/*.test.ts\"],\n globals: true,\n coverage: {\n provider: \"v8\",\n- reporter: [\"text\", \"html\"],\n+ reporter: [\"text\", \"json\", \"html\"],\n include: [\"src/**/*.ts\"],\n+ exclude: [\n+ \"src/**/*.test.ts\",\n+ \"node_modules/\",\n+ \"dist/**\",\n+ \"vitest.config.ts\",\n+ \"vite.config.ts\",\n+ \"eslint.config.mjs\",\n+ ],\n },\n },\n });\n-\n\n\nAnalyze these changes and write clear release notes. Consider:\n- What's the main story of this release?\n- What problems does it solve?\n- What's the impact on users and developers?\n- Are there breaking changes?\n\nIf context information is provided, use it only if relevant to this specific package.\nDon't force connections that don't exist - if context describes changes in other packages\nor unrelated features, simply ignore it and focus on what actually changed in this release.\n\nInvestigate as needed to write accurate, helpful release notes."
63
+ },
64
+ {
65
+ "role": "assistant",
66
+ "content": null,
67
+ "tool_calls": [
68
+ {
69
+ "id": "call_NEPK2KmzbDGgDpJQc9ndxz4s",
70
+ "type": "function",
71
+ "function": {
72
+ "name": "get_release_stats",
73
+ "arguments": "{\"fromRef\": \"main\", \"toRef\": \"HEAD\"}"
74
+ }
75
+ },
76
+ {
77
+ "id": "call_hJD9Dqbj0Gfu7KKAjNFzU9wu",
78
+ "type": "function",
79
+ "function": {
80
+ "name": "get_breaking_changes",
81
+ "arguments": "{\"fromRef\": \"main\", \"toRef\": \"HEAD\"}"
82
+ }
83
+ },
84
+ {
85
+ "id": "call_jehjwgY8GdlzbEXJHNFoo2xF",
86
+ "type": "function",
87
+ "function": {
88
+ "name": "analyze_commit_patterns",
89
+ "arguments": "{\"fromRef\": \"main\", \"toRef\": \"HEAD\"}"
90
+ }
91
+ },
92
+ {
93
+ "id": "call_NwGhEcZZ80noAePtssbXQbHC",
94
+ "type": "function",
95
+ "function": {
96
+ "name": "get_file_content",
97
+ "arguments": "{\"filePath\": \"package.json\", \"includeLineNumbers\": false}"
98
+ }
99
+ },
100
+ {
101
+ "id": "call_MSuNxGqNyJLVv9Ap5lIur1Hq",
102
+ "type": "function",
103
+ "function": {
104
+ "name": "get_file_content",
105
+ "arguments": "{\"filePath\": \"vitest.config.ts\", \"includeLineNumbers\": false}"
106
+ }
107
+ },
108
+ {
109
+ "id": "call_rjxs95Ki16rY99fzYqC0ghg7",
110
+ "type": "function",
111
+ "function": {
112
+ "name": "get_file_content",
113
+ "arguments": "{\"filePath\": \"tests/index.test.ts\", \"includeLineNumbers\": false}"
114
+ }
115
+ }
116
+ ]
117
+ },
118
+ {
119
+ "role": "tool",
120
+ "tool_call_id": "call_NEPK2KmzbDGgDpJQc9ndxz4s",
121
+ "content": "Total commits: 2\n\nContributors:\n 2\tTim O'Brien\n\n\nFile changes: 5 files changed, 626 insertions(+), 14 deletions(-)\n\nTop 10 most changed files:\n vitest.config.ts | 13 +-\n package.json | 13 +-\n package-lock.json | 608 ++++++++++++++++++++++++++++++++++++++++++-\n 5 files changed, 626 insertions(+), 14 deletions(-)\n {src => tests}/index.test.ts | 2 +-\n .kodrdriv-test-cache.json | 4 +-\n",
122
+ "name": "get_release_stats"
123
+ },
124
+ {
125
+ "role": "tool",
126
+ "tool_call_id": "call_hJD9Dqbj0Gfu7KKAjNFzU9wu",
127
+ "content": "No obvious breaking changes detected. Manual review recommended for API changes.",
128
+ "name": "get_breaking_changes"
129
+ },
130
+ {
131
+ "role": "tool",
132
+ "tool_call_id": "call_jehjwgY8GdlzbEXJHNFoo2xF",
133
+ "content": "\nTop keywords in commits:\n updated: 1\n separated: 1\n tests: 1",
134
+ "name": "analyze_commit_patterns"
135
+ },
136
+ {
137
+ "role": "tool",
138
+ "tool_call_id": "call_NwGhEcZZ80noAePtssbXQbHC",
139
+ "content": "{\n \"name\": \"@riotprompt/execution-openai\",\n \"version\": \"0.0.2\",\n \"description\": \"OpenAI provider for execution - implements Provider interface\",\n \"type\": \"module\",\n \"main\": \"./dist/index.cjs\",\n \"module\": \"./dist/index.js\",\n \"types\": \"./dist/index.d.ts\",\n \"exports\": {\n \".\": {\n \"types\": \"./dist/index.d.ts\",\n \"import\": \"./dist/index.js\",\n \"require\": \"./dist/index.cjs\"\n }\n },\n \"scripts\": {\n \"clean\": \"rm -rf dist\",\n \"build\": \"vite build\",\n \"test\": \"vitest run --coverage\",\n \"test:coverage\": \"vitest run --coverage\",\n \"lint\": \"eslint src\",\n \"precommit\": \"npm run lint && npm run test\",\n \"prepublishOnly\": \"npm run clean && npm run build\"\n },\n \"keywords\": [\n \"llm\",\n \"openai\",\n \"gpt\",\n \"execution\",\n \"provider\"\n ],\n \"author\": \"Tim O'Brien <tobrien@discursive.com>\",\n \"license\": \"Apache-2.0\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"https://github.com/kjerneverk/execution-openai\"\n },\n \"dependencies\": {\n \"openai\": \"^4.103.0\",\n \"tiktoken\": \"^1.0.21\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^25.0.6\",\n \"@typescript-eslint/eslint-plugin\": \"^8.33.1\",\n \"@typescript-eslint/parser\": \"^8.33.1\",\n \"@vitest/coverage-v8\": \"^3.2.4\",\n \"eslint\": \"^9.28.0\",\n \"globals\": \"^16.2.0\",\n \"typescript\": \"^5.8.3\",\n \"vite\": \"^7.0.4\",\n \"vite-plugin-dts\": \"^4.5.4\",\n \"vitest\": \"^3.2.4\"\n }\n}\n",
140
+ "name": "get_file_content"
141
+ },
142
+ {
143
+ "role": "tool",
144
+ "tool_call_id": "call_MSuNxGqNyJLVv9Ap5lIur1Hq",
145
+ "content": "import { defineConfig } from \"vitest/config\";\n\nexport default defineConfig({\n test: {\n include: [\"tests/**/*.test.ts\"],\n globals: true,\n coverage: {\n provider: \"v8\",\n reporter: [\"text\", \"json\", \"html\"],\n include: [\"src/**/*.ts\"],\n exclude: [\n \"src/**/*.test.ts\",\n \"node_modules/\",\n \"dist/**\",\n \"vitest.config.ts\",\n \"vite.config.ts\",\n \"eslint.config.mjs\",\n ],\n },\n },\n});\n",
146
+ "name": "get_file_content"
147
+ },
148
+ {
149
+ "role": "tool",
150
+ "tool_call_id": "call_rjxs95Ki16rY99fzYqC0ghg7",
151
+ "content": "/**\n * Tests for execution-openai package\n */\n\nimport { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';\nimport {\n OpenAIProvider,\n createOpenAIProvider,\n VERSION,\n type Message,\n type Request,\n type ExecutionOptions,\n type ProviderResponse,\n type Provider,\n} from '../src/index.js';\n\ndescribe('OpenAIProvider', () => {\n let provider: OpenAIProvider;\n\n beforeEach(() => {\n provider = new OpenAIProvider();\n });\n\n describe('name', () => {\n it('should have name \"openai\"', () => {\n expect(provider.name).toBe('openai');\n });\n });\n\n describe('supportsModel', () => {\n it('should support GPT models', () => {\n expect(provider.supportsModel('gpt-4')).toBe(true);\n expect(provider.supportsModel('gpt-4o')).toBe(true);\n expect(provider.supportsModel('gpt-4-turbo')).toBe(true);\n expect(provider.supportsModel('gpt-3.5-turbo')).toBe(true);\n });\n\n it('should support O1/O3/O4 models', () => {\n expect(provider.supportsModel('o1-preview')).toBe(true);\n expect(provider.supportsModel('o1-mini')).toBe(true);\n expect(provider.supportsModel('o3-mini')).toBe(true);\n expect(provider.supportsModel('o4-mini')).toBe(true);\n });\n\n it('should not support Claude models', () => {\n expect(provider.supportsModel('claude-3-opus-20240229')).toBe(false);\n expect(provider.supportsModel('claude-3-sonnet-20240229')).toBe(false);\n });\n\n it('should not support Gemini models', () => {\n expect(provider.supportsModel('gemini-1.5-pro')).toBe(false);\n expect(provider.supportsModel('gemini-1.5-flash')).toBe(false);\n });\n\n it('should return true for empty/undefined model (default to OpenAI)', () => {\n expect(provider.supportsModel('')).toBe(true);\n });\n });\n\n describe('execute', () => {\n const originalEnv = process.env;\n\n beforeEach(() => {\n process.env = { ...originalEnv };\n delete process.env.OPENAI_API_KEY;\n });\n\n afterEach(() => {\n process.env = originalEnv;\n });\n\n it('should throw error when no API key is provided', async () => {\n const request: Request = {\n messages: [{ role: 'user', content: 'Hello' }],\n model: 'gpt-4',\n addMessage: vi.fn(),\n };\n\n await expect(provider.execute(request)).rejects.toThrow(\n 'OpenAI API key is required'\n );\n });\n\n it('should throw error when API key is empty string', async () => {\n const request: Request = {\n messages: [{ role: 'user', content: 'Hello' }],\n model: 'gpt-4',\n addMessage: vi.fn(),\n };\n\n await expect(provider.execute(request, { apiKey: '' })).rejects.toThrow(\n 'OpenAI API key is required'\n );\n });\n });\n\n describe('implements Provider interface', () => {\n it('should satisfy Provider interface', () => {\n const p: Provider = provider;\n expect(p.name).toBe('openai');\n expect(typeof p.execute).toBe('function');\n expect(typeof p.supportsModel).toBe('function');\n });\n });\n});\n\ndescribe('createOpenAIProvider', () => {\n it('should create a new OpenAIProvider instance', () => {\n const provider = createOpenAIProvider();\n expect(provider).toBeInstanceOf(OpenAIProvider);\n expect(provider.name).toBe('openai');\n });\n});\n\ndescribe('VERSION', () => {\n it('should export version string', () => {\n expect(VERSION).toBe('0.0.1');\n });\n});\n\ndescribe('Type exports', () => {\n it('should export Message type', () => {\n const msg: Message = {\n role: 'user',\n content: 'Hello',\n };\n expect(msg.role).toBe('user');\n expect(msg.content).toBe('Hello');\n });\n\n it('should support all message roles', () => {\n const roles: Message['role'][] = ['user', 'assistant', 'system', 'developer', 'tool'];\n roles.forEach(role => {\n const msg: Message = { role, content: 'test' };\n expect(msg.role).toBe(role);\n });\n });\n\n it('should support array content', () => {\n const msg: Message = {\n role: 'user',\n content: ['Hello', 'World'],\n };\n expect(Array.isArray(msg.content)).toBe(true);\n });\n\n it('should support null content', () => {\n const msg: Message = {\n role: 'assistant',\n content: null,\n };\n expect(msg.content).toBeNull();\n });\n\n it('should export ExecutionOptions type', () => {\n const opts: ExecutionOptions = {\n apiKey: 'test-key',\n model: 'gpt-4',\n temperature: 0.7,\n maxTokens: 1000,\n timeout: 30000,\n retries: 3,\n };\n expect(opts.apiKey).toBe('test-key');\n expect(opts.temperature).toBe(0.7);\n });\n\n it('should export ProviderResponse type', () => {\n const response: ProviderResponse = {\n content: 'Hello!',\n model: 'gpt-4',\n usage: {\n inputTokens: 10,\n outputTokens: 5,\n },\n };\n expect(response.content).toBe('Hello!');\n expect(response.usage?.inputTokens).toBe(10);\n });\n\n it('should support toolCalls in ProviderResponse', () => {\n const response: ProviderResponse = {\n content: '',\n model: 'gpt-4',\n toolCalls: [\n {\n id: 'call_123',\n type: 'function',\n function: {\n name: 'get_weather',\n arguments: '{\"location\": \"NYC\"}',\n },\n },\n ],\n };\n expect(response.toolCalls).toHaveLength(1);\n expect(response.toolCalls?.[0].function.name).toBe('get_weather');\n });\n});\n\n",
152
+ "name": "get_file_content"
153
+ },
154
+ {
155
+ "role": "assistant",
156
+ "content": null,
157
+ "tool_calls": [
158
+ {
159
+ "id": "call_kQ0aZud3vCoZhOzob1QKRQk4",
160
+ "type": "function",
161
+ "function": {
162
+ "name": "get_file_content",
163
+ "arguments": "{\"filePath\": \"src/index.ts\", \"includeLineNumbers\": false}"
164
+ }
165
+ },
166
+ {
167
+ "id": "call_jDhDjLpswM5uuE0bFwaf55ZX",
168
+ "type": "function",
169
+ "function": {
170
+ "name": "get_related_tests",
171
+ "arguments": "{\"filePaths\": [\"src/index.ts\"]}"
172
+ }
173
+ },
174
+ {
175
+ "id": "call_YHPoVHNd6SDyZvvqmLYEJN3k",
176
+ "type": "function",
177
+ "function": {
178
+ "name": "get_file_dependencies",
179
+ "arguments": "{\"filePaths\": [\"src/index.ts\"]}"
180
+ }
181
+ }
182
+ ]
183
+ },
184
+ {
185
+ "role": "tool",
186
+ "tool_call_id": "call_kQ0aZud3vCoZhOzob1QKRQk4",
187
+ "content": "/**\n * Execution OpenAI Package\n *\n * OpenAI provider implementation for LLM execution.\n *\n * @packageDocumentation\n */\n\nimport OpenAI from 'openai';\n\n// ===== INLINE TYPES (from 'execution' package) =====\n// These types are duplicated here for build independence.\n// When 'execution' is published, these can be imported from there.\n\nexport type Model = string;\n\nexport interface Message {\n role: 'user' | 'assistant' | 'system' | 'developer' | 'tool';\n content: string | string[] | null;\n name?: string;\n}\n\nexport interface Request {\n messages: Message[];\n model: Model;\n responseFormat?: any;\n validator?: any;\n addMessage(message: Message): void;\n}\n\nexport interface ProviderResponse {\n content: string;\n model: string;\n usage?: {\n inputTokens: number;\n outputTokens: number;\n };\n toolCalls?: Array<{\n id: string;\n type: 'function';\n function: {\n name: string;\n arguments: string;\n };\n }>;\n}\n\nexport interface ExecutionOptions {\n apiKey?: string;\n model?: string;\n temperature?: number;\n maxTokens?: number;\n timeout?: number;\n retries?: number;\n}\n\nexport interface Provider {\n readonly name: string;\n execute(request: Request, options?: ExecutionOptions): Promise<ProviderResponse>;\n supportsModel?(model: Model): boolean;\n}\n\n/**\n * OpenAI Provider implementation\n */\nexport class OpenAIProvider implements Provider {\n readonly name = 'openai';\n\n /**\n * Check if this provider supports a given model\n */\n supportsModel(model: Model): boolean {\n if (!model) return true; // Default to OpenAI\n return (\n model.startsWith('gpt') ||\n model.startsWith('o1') ||\n model.startsWith('o3') ||\n model.startsWith('o4')\n );\n }\n\n /**\n * Execute a request against OpenAI\n */\n async execute(\n request: Request,\n options: ExecutionOptions = {}\n ): Promise<ProviderResponse> {\n const apiKey = options.apiKey || process.env.OPENAI_API_KEY;\n if (!apiKey) throw new Error('OpenAI API key is required');\n\n const client = new OpenAI({ apiKey });\n\n const model = options.model || request.model || 'gpt-4';\n\n // Convert messages to OpenAI format\n const messages = request.messages.map((msg) => {\n const role =\n msg.role === 'developer' ? 'system' : msg.role;\n\n return {\n role: role,\n content:\n typeof msg.content === 'string'\n ? msg.content\n : JSON.stringify(msg.content),\n name: msg.name,\n } as any;\n });\n\n const response = await client.chat.completions.create({\n model: model,\n messages: messages,\n temperature: options.temperature,\n max_tokens: options.maxTokens,\n response_format: request.responseFormat,\n });\n\n const choice = response.choices[0];\n\n return {\n content: choice.message.content || '',\n model: response.model,\n usage: response.usage\n ? {\n inputTokens: response.usage.prompt_tokens,\n outputTokens: response.usage.completion_tokens,\n }\n : undefined,\n toolCalls: choice.message.tool_calls?.map((tc) => ({\n id: tc.id,\n type: 'function' as const,\n function: {\n name: tc.function.name,\n arguments: tc.function.arguments,\n },\n })),\n };\n }\n}\n\n/**\n * Create a new OpenAI provider instance\n */\nexport function createOpenAIProvider(): OpenAIProvider {\n return new OpenAIProvider();\n}\n\n/**\n * Package version\n */\nexport const VERSION = '0.0.1';\n\nexport default OpenAIProvider;\n",
188
+ "name": "get_file_content"
189
+ },
190
+ {
191
+ "role": "tool",
192
+ "tool_call_id": "call_jDhDjLpswM5uuE0bFwaf55ZX",
193
+ "content": "Found related test files:\nsrc/index.ts",
194
+ "name": "get_related_tests"
195
+ },
196
+ {
197
+ "role": "tool",
198
+ "tool_call_id": "call_YHPoVHNd6SDyZvvqmLYEJN3k",
199
+ "content": "No files found that import the specified files",
200
+ "name": "get_file_dependencies"
201
+ },
202
+ {
203
+ "role": "assistant",
204
+ "content": null,
205
+ "tool_calls": [
206
+ {
207
+ "id": "call_Gr4IhGlCF0jmGBz9Xg514MDf",
208
+ "type": "function",
209
+ "function": {
210
+ "name": "get_file_history",
211
+ "arguments": "{\"filePaths\":[\"src/index.test.ts\",\"tests/index.test.ts\",\"vitest.config.ts\",\"package.json\",\"src/index.ts\"],\"limit\":10,\"format\":\"detailed\"}"
212
+ }
213
+ }
214
+ ]
215
+ },
216
+ {
217
+ "role": "tool",
218
+ "tool_call_id": "call_Gr4IhGlCF0jmGBz9Xg514MDf",
219
+ "content": "43f7d7086e7fe112c171b0a0595251d47481f7d8\nTim O'Brien (tobrien@discursive.com)\nSat Jan 10 13:19:17 2026 -0800\nUpdated and separated tests\n\n\n---\n7948ae0dfcf8860fcbcc9965dff01f047e52a5c2\nTim O'Brien (tobrien@discursive.com)\nSat Jan 10 11:22:13 2026 -0800\n0.0.2-dev.0\n\n\n---\n52ade0898ae977c0e7058b0aa15568a9ded40825\nTim O'Brien (tobrien@discursive.com)\nSat Jan 10 11:21:52 2026 -0800\nFirst commit\n\n\n---\n",
220
+ "name": "get_file_history"
221
+ },
222
+ {
223
+ "role": "assistant",
224
+ "content": "RELEASE_NOTES:\n{\n \"title\": \"@riotprompt/execution-openai 0.0.2 — test suite moved to /tests with default coverage + improved publish scripts\",\n \"body\": \"## Summary\\nThis release focuses on developer workflow improvements: tests are now separated from source, `npm test` produces coverage by default (including JSON output for CI tooling), and publish-time scripts better ensure clean builds.\\n\\n## Changes\\n### Testing & coverage\\n- **Moved tests out of `src/` into `tests/`** (e.g., `src/index.test.ts` → `tests/index.test.ts`) to keep source and tests clearly separated.\\n- **Vitest now only discovers tests under `tests/**/*.test.ts`**.\\n - If you previously relied on tests located under `src/**`, they will no longer run unless moved to `tests/`.\\n- **Coverage is enabled by default**:\\n - `npm test` now runs `vitest run --coverage`.\\n - Added `test:coverage` as an explicit alias.\\n- **Coverage reporting expanded** to include `json` output (in addition to `text` and `html`) and a more explicit exclude list (e.g., `dist/**`, config files, etc.).\\n- Added **`@vitest/coverage-v8`** to `devDependencies` (and updated `package-lock.json`) to support v8 coverage.\\n\\n### Package scripts & publishing\\n- Added `clean` script (`rm -rf dist`).\\n- Added `precommit` hook script that runs `lint` and `test`.\\n- Added `prepublishOnly` to enforce a clean rebuild before publishing (`clean` then `build`).\\n\\n### Package metadata\\n- Bumped package version **0.0.1 → 0.0.2**.\\n- Normalized `repository.url` (removed the `git+` prefix).\\n\\n## Impact\\n### For package users\\n- No runtime/API behavior changes were introduced in this diff.\\n\\n### For contributors/CI\\n- `npm test` is now slower and produces coverage artifacts by default.\\n- CI systems that expect test files under `src/` must move them to `tests/` (or adjust Vitest configuration).\\n\\n## Breaking changes\\n- **Potential workflow breaking change (dev/CI):** tests under `src/**/*.test.ts` are no longer included by default.\\n- No breaking changes to the published runtime API were detected in this range.\\n\\n## Known consideration\\n- The package.json version is now **0.0.2**, but `src/index.ts` still exports `VERSION = '0.0.1'`. If you use the exported `VERSION` constant, it may not reflect the published package version yet.\"\n}"
225
+ }
226
+ ]
227
+ ```
228
+
229
+ </details>
230
+
231
+ ## Generated Release Notes
232
+
233
+ ### Title
234
+ ```
235
+ @riotprompt/execution-openai 0.0.2 — test suite moved to /tests with default coverage + improved publish scripts
236
+ ```
237
+
238
+ ### Body
239
+ ```markdown
240
+ ## Summary
241
+ This release focuses on developer workflow improvements: tests are now separated from source, `npm test` produces coverage by default (including JSON output for CI tooling), and publish-time scripts better ensure clean builds.
242
+
243
+ ## Changes
244
+ ### Testing & coverage
245
+ - **Moved tests out of `src/` into `tests/`** (e.g., `src/index.test.ts` → `tests/index.test.ts`) to keep source and tests clearly separated.
246
+ - **Vitest now only discovers tests under `tests/**/*.test.ts`**.
247
+ - If you previously relied on tests located under `src/**`, they will no longer run unless moved to `tests/`.
248
+ - **Coverage is enabled by default**:
249
+ - `npm test` now runs `vitest run --coverage`.
250
+ - Added `test:coverage` as an explicit alias.
251
+ - **Coverage reporting expanded** to include `json` output (in addition to `text` and `html`) and a more explicit exclude list (e.g., `dist/**`, config files, etc.).
252
+ - Added **`@vitest/coverage-v8`** to `devDependencies` (and updated `package-lock.json`) to support v8 coverage.
253
+
254
+ ### Package scripts & publishing
255
+ - Added `clean` script (`rm -rf dist`).
256
+ - Added `precommit` hook script that runs `lint` and `test`.
257
+ - Added `prepublishOnly` to enforce a clean rebuild before publishing (`clean` then `build`).
258
+
259
+ ### Package metadata
260
+ - Bumped package version **0.0.1 → 0.0.2**.
261
+ - Normalized `repository.url` (removed the `git+` prefix).
262
+
263
+ ## Impact
264
+ ### For package users
265
+ - No runtime/API behavior changes were introduced in this diff.
266
+
267
+ ### For contributors/CI
268
+ - `npm test` is now slower and produces coverage artifacts by default.
269
+ - CI systems that expect test files under `src/` must move them to `tests/` (or adjust Vitest configuration).
270
+
271
+ ## Breaking changes
272
+ - **Potential workflow breaking change (dev/CI):** tests under `src/**/*.test.ts` are no longer included by default.
273
+ - No breaking changes to the published runtime API were detected in this range.
274
+
275
+ ## Known consideration
276
+ - The package.json version is now **0.0.2**, but `src/index.ts` still exports `VERSION = '0.0.1'`. If you use the exported `VERSION` constant, it may not reflect the published package version yet.
277
+ ```