qlogicagent 0.2.1 → 0.4.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 (226) hide show
  1. package/README.md +45 -45
  2. package/package.json +56 -42
  3. package/dist/agent/agent.d.ts +0 -43
  4. package/dist/agent/agent.js +0 -113
  5. package/dist/agent/tool-loop.d.ts +0 -64
  6. package/dist/agent/tool-loop.js +0 -575
  7. package/dist/agent/types.d.ts +0 -175
  8. package/dist/agent/types.js +0 -14
  9. package/dist/cli/main.d.ts +0 -11
  10. package/dist/cli/main.js +0 -23
  11. package/dist/cli/stdio-server.d.ts +0 -45
  12. package/dist/cli/stdio-server.js +0 -463
  13. package/dist/config/config.d.ts +0 -17
  14. package/dist/config/config.js +0 -21
  15. package/dist/contracts/hooks.d.ts +0 -120
  16. package/dist/contracts/hooks.js +0 -7
  17. package/dist/contracts/index.d.ts +0 -10
  18. package/dist/contracts/index.js +0 -10
  19. package/dist/contracts/planner.d.ts +0 -35
  20. package/dist/contracts/planner.js +0 -2
  21. package/dist/contracts/skill-candidate.d.ts +0 -63
  22. package/dist/contracts/skill-candidate.js +0 -195
  23. package/dist/contracts/todo.d.ts +0 -14
  24. package/dist/contracts/todo.js +0 -9
  25. package/dist/index.d.ts +0 -13
  26. package/dist/index.js +0 -15
  27. package/dist/llm/builtin-providers.d.ts +0 -10
  28. package/dist/llm/builtin-providers.js +0 -531
  29. package/dist/llm/index.d.ts +0 -15
  30. package/dist/llm/index.js +0 -14
  31. package/dist/llm/llm-client.d.ts +0 -43
  32. package/dist/llm/llm-client.js +0 -67
  33. package/dist/llm/model-catalog.d.ts +0 -53
  34. package/dist/llm/model-catalog.js +0 -191
  35. package/dist/llm/provider-def.d.ts +0 -59
  36. package/dist/llm/provider-def.js +0 -12
  37. package/dist/llm/provider-registry.d.ts +0 -54
  38. package/dist/llm/provider-registry.js +0 -147
  39. package/dist/llm/transport.d.ts +0 -62
  40. package/dist/llm/transport.js +0 -27
  41. package/dist/llm/transports/anthropic-messages.d.ts +0 -31
  42. package/dist/llm/transports/anthropic-messages.js +0 -293
  43. package/dist/llm/transports/openai-chat.d.ts +0 -36
  44. package/dist/llm/transports/openai-chat.js +0 -165
  45. package/dist/orchestration/agent-registry.d.ts +0 -41
  46. package/dist/orchestration/agent-registry.js +0 -116
  47. package/dist/orchestration/approval-aware-tool-plan.d.ts +0 -32
  48. package/dist/orchestration/approval-aware-tool-plan.js +0 -87
  49. package/dist/orchestration/context-compression.d.ts +0 -220
  50. package/dist/orchestration/context-compression.js +0 -583
  51. package/dist/orchestration/conversation-repair.d.ts +0 -61
  52. package/dist/orchestration/conversation-repair.js +0 -429
  53. package/dist/orchestration/curator-scheduler.d.ts +0 -119
  54. package/dist/orchestration/curator-scheduler.js +0 -135
  55. package/dist/orchestration/embedded-failover-policy.d.ts +0 -110
  56. package/dist/orchestration/embedded-failover-policy.js +0 -168
  57. package/dist/orchestration/error-classification.d.ts +0 -12
  58. package/dist/orchestration/error-classification.js +0 -77
  59. package/dist/orchestration/failover-classification.d.ts +0 -8
  60. package/dist/orchestration/failover-classification.js +0 -381
  61. package/dist/orchestration/failover-error.d.ts +0 -33
  62. package/dist/orchestration/failover-error.js +0 -198
  63. package/dist/orchestration/fork-subagent.d.ts +0 -100
  64. package/dist/orchestration/fork-subagent.js +0 -98
  65. package/dist/orchestration/index.d.ts +0 -120
  66. package/dist/orchestration/index.js +0 -267
  67. package/dist/orchestration/memory-flush-policy.d.ts +0 -57
  68. package/dist/orchestration/memory-flush-policy.js +0 -85
  69. package/dist/orchestration/memory-provider.d.ts +0 -14
  70. package/dist/orchestration/memory-provider.js +0 -2
  71. package/dist/orchestration/parallel-tool-calls.d.ts +0 -41
  72. package/dist/orchestration/parallel-tool-calls.js +0 -59
  73. package/dist/orchestration/prompt-cache-strategy.d.ts +0 -126
  74. package/dist/orchestration/prompt-cache-strategy.js +0 -228
  75. package/dist/orchestration/reactive-compact.d.ts +0 -73
  76. package/dist/orchestration/reactive-compact.js +0 -78
  77. package/dist/orchestration/retry-loop.d.ts +0 -22
  78. package/dist/orchestration/retry-loop.js +0 -24
  79. package/dist/orchestration/skill-candidate.d.ts +0 -52
  80. package/dist/orchestration/skill-candidate.js +0 -141
  81. package/dist/orchestration/skill-consolidation.d.ts +0 -123
  82. package/dist/orchestration/skill-consolidation.js +0 -220
  83. package/dist/orchestration/skill-improvement.d.ts +0 -59
  84. package/dist/orchestration/skill-improvement.js +0 -66
  85. package/dist/orchestration/skill-similarity.d.ts +0 -98
  86. package/dist/orchestration/skill-similarity.js +0 -131
  87. package/dist/orchestration/streaming-tool-executor.d.ts +0 -73
  88. package/dist/orchestration/streaming-tool-executor.js +0 -96
  89. package/dist/orchestration/team-orchestration.d.ts +0 -195
  90. package/dist/orchestration/team-orchestration.js +0 -369
  91. package/dist/orchestration/team-tool-loop-wiring.d.ts +0 -92
  92. package/dist/orchestration/team-tool-loop-wiring.js +0 -147
  93. package/dist/orchestration/tool-choice-policy.d.ts +0 -54
  94. package/dist/orchestration/tool-choice-policy.js +0 -164
  95. package/dist/orchestration/tool-loop-state.d.ts +0 -50
  96. package/dist/orchestration/tool-loop-state.js +0 -133
  97. package/dist/orchestration/tool-schema.d.ts +0 -39
  98. package/dist/orchestration/tool-schema.js +0 -297
  99. package/dist/orchestration/transcript-repair.d.ts +0 -42
  100. package/dist/orchestration/transcript-repair.js +0 -426
  101. package/dist/orchestration/turn-loop-guard.d.ts +0 -86
  102. package/dist/orchestration/turn-loop-guard.js +0 -92
  103. package/dist/orchestration/web-browser-policy.d.ts +0 -17
  104. package/dist/orchestration/web-browser-policy.js +0 -39
  105. package/dist/runtime/context-compression.d.ts +0 -61
  106. package/dist/runtime/context-compression.js +0 -274
  107. package/dist/runtime/hook-registry.d.ts +0 -12
  108. package/dist/runtime/hook-registry.js +0 -53
  109. package/dist/runtime/memory-hooks.d.ts +0 -23
  110. package/dist/runtime/memory-hooks.js +0 -65
  111. package/dist/runtime/tool-eligibility.d.ts +0 -59
  112. package/dist/runtime/tool-eligibility.js +0 -111
  113. package/dist/skills/index.d.ts +0 -108
  114. package/dist/skills/index.js +0 -82
  115. package/dist/skills/memory-extractor.d.ts +0 -64
  116. package/dist/skills/memory-extractor.js +0 -173
  117. package/dist/skills/memory-query-tool.d.ts +0 -43
  118. package/dist/skills/memory-query-tool.js +0 -127
  119. package/dist/skills/memory-store.d.ts +0 -66
  120. package/dist/skills/memory-store.js +0 -228
  121. package/dist/skills/memory-tool.d.ts +0 -67
  122. package/dist/skills/memory-tool.js +0 -192
  123. package/dist/skills/portable-tool.d.ts +0 -71
  124. package/dist/skills/portable-tool.js +0 -14
  125. package/dist/skills/qmemory-adapter.d.ts +0 -52
  126. package/dist/skills/qmemory-adapter.js +0 -165
  127. package/dist/skills/skill-frontmatter.d.ts +0 -19
  128. package/dist/skills/skill-frontmatter.js +0 -344
  129. package/dist/skills/skill-guard.d.ts +0 -23
  130. package/dist/skills/skill-guard.js +0 -229
  131. package/dist/skills/skill-loader.d.ts +0 -16
  132. package/dist/skills/skill-loader.js +0 -303
  133. package/dist/skills/skill-source.d.ts +0 -119
  134. package/dist/skills/skill-source.js +0 -126
  135. package/dist/skills/skill-types.d.ts +0 -199
  136. package/dist/skills/skill-types.js +0 -6
  137. package/dist/skills/think-tool.d.ts +0 -16
  138. package/dist/skills/think-tool.js +0 -59
  139. package/dist/skills/todo-tool.d.ts +0 -63
  140. package/dist/skills/todo-tool.js +0 -114
  141. package/dist/skills/tools/agent-tool.d.ts +0 -91
  142. package/dist/skills/tools/agent-tool.js +0 -142
  143. package/dist/skills/tools/apply-patch-tool.d.ts +0 -29
  144. package/dist/skills/tools/apply-patch-tool.js +0 -184
  145. package/dist/skills/tools/ask-user-tool.d.ts +0 -80
  146. package/dist/skills/tools/ask-user-tool.js +0 -121
  147. package/dist/skills/tools/brief-tool.d.ts +0 -74
  148. package/dist/skills/tools/brief-tool.js +0 -95
  149. package/dist/skills/tools/browser-tool.d.ts +0 -114
  150. package/dist/skills/tools/browser-tool.js +0 -155
  151. package/dist/skills/tools/checkpoint-tool.d.ts +0 -66
  152. package/dist/skills/tools/checkpoint-tool.js +0 -102
  153. package/dist/skills/tools/config-tool.d.ts +0 -63
  154. package/dist/skills/tools/config-tool.js +0 -143
  155. package/dist/skills/tools/cron-tool.d.ts +0 -116
  156. package/dist/skills/tools/cron-tool.js +0 -175
  157. package/dist/skills/tools/edit-tool.d.ts +0 -43
  158. package/dist/skills/tools/edit-tool.js +0 -70
  159. package/dist/skills/tools/exec-tool.d.ts +0 -102
  160. package/dist/skills/tools/exec-tool.js +0 -133
  161. package/dist/skills/tools/image-generate-tool.d.ts +0 -62
  162. package/dist/skills/tools/image-generate-tool.js +0 -67
  163. package/dist/skills/tools/instructions-tool.d.ts +0 -103
  164. package/dist/skills/tools/instructions-tool.js +0 -187
  165. package/dist/skills/tools/lsp-tool.d.ts +0 -153
  166. package/dist/skills/tools/lsp-tool.js +0 -227
  167. package/dist/skills/tools/mcp-client-types.d.ts +0 -269
  168. package/dist/skills/tools/mcp-client-types.js +0 -53
  169. package/dist/skills/tools/mcp-tool.d.ts +0 -249
  170. package/dist/skills/tools/mcp-tool.js +0 -503
  171. package/dist/skills/tools/memory-tool.d.ts +0 -74
  172. package/dist/skills/tools/memory-tool.js +0 -88
  173. package/dist/skills/tools/monitor-tool.d.ts +0 -113
  174. package/dist/skills/tools/monitor-tool.js +0 -131
  175. package/dist/skills/tools/music-generate-tool.d.ts +0 -55
  176. package/dist/skills/tools/music-generate-tool.js +0 -62
  177. package/dist/skills/tools/notify-tool.d.ts +0 -53
  178. package/dist/skills/tools/notify-tool.js +0 -62
  179. package/dist/skills/tools/patch-tool.d.ts +0 -45
  180. package/dist/skills/tools/patch-tool.js +0 -505
  181. package/dist/skills/tools/pdf-tool.d.ts +0 -66
  182. package/dist/skills/tools/pdf-tool.js +0 -88
  183. package/dist/skills/tools/plan-mode-tool.d.ts +0 -59
  184. package/dist/skills/tools/plan-mode-tool.js +0 -122
  185. package/dist/skills/tools/read-tool.d.ts +0 -51
  186. package/dist/skills/tools/read-tool.js +0 -84
  187. package/dist/skills/tools/repl-tool.d.ts +0 -70
  188. package/dist/skills/tools/repl-tool.js +0 -69
  189. package/dist/skills/tools/search-tool.d.ts +0 -112
  190. package/dist/skills/tools/search-tool.js +0 -225
  191. package/dist/skills/tools/send-message-tool.d.ts +0 -51
  192. package/dist/skills/tools/send-message-tool.js +0 -76
  193. package/dist/skills/tools/skill-list-tool.d.ts +0 -33
  194. package/dist/skills/tools/skill-list-tool.js +0 -54
  195. package/dist/skills/tools/skill-manage-tool.d.ts +0 -73
  196. package/dist/skills/tools/skill-manage-tool.js +0 -153
  197. package/dist/skills/tools/skill-view-tool.d.ts +0 -37
  198. package/dist/skills/tools/skill-view-tool.js +0 -72
  199. package/dist/skills/tools/sleep-tool.d.ts +0 -49
  200. package/dist/skills/tools/sleep-tool.js +0 -81
  201. package/dist/skills/tools/structured-output-tool.d.ts +0 -116
  202. package/dist/skills/tools/structured-output-tool.js +0 -176
  203. package/dist/skills/tools/task-tool.d.ts +0 -104
  204. package/dist/skills/tools/task-tool.js +0 -161
  205. package/dist/skills/tools/team-tool.d.ts +0 -89
  206. package/dist/skills/tools/team-tool.js +0 -105
  207. package/dist/skills/tools/tool-search-tool.d.ts +0 -51
  208. package/dist/skills/tools/tool-search-tool.js +0 -110
  209. package/dist/skills/tools/tts-tool.d.ts +0 -38
  210. package/dist/skills/tools/tts-tool.js +0 -45
  211. package/dist/skills/tools/video-edit-tool.d.ts +0 -69
  212. package/dist/skills/tools/video-edit-tool.js +0 -74
  213. package/dist/skills/tools/video-generate-tool.d.ts +0 -62
  214. package/dist/skills/tools/video-generate-tool.js +0 -66
  215. package/dist/skills/tools/video-merge-tool.d.ts +0 -105
  216. package/dist/skills/tools/video-merge-tool.js +0 -92
  217. package/dist/skills/tools/video-upscale-tool.d.ts +0 -45
  218. package/dist/skills/tools/video-upscale-tool.js +0 -52
  219. package/dist/skills/tools/web-fetch-tool.d.ts +0 -78
  220. package/dist/skills/tools/web-fetch-tool.js +0 -92
  221. package/dist/skills/tools/web-search-tool.d.ts +0 -57
  222. package/dist/skills/tools/web-search-tool.js +0 -86
  223. package/dist/skills/tools/worktree-tool.d.ts +0 -69
  224. package/dist/skills/tools/worktree-tool.js +0 -147
  225. package/dist/skills/tools/write-tool.d.ts +0 -45
  226. package/dist/skills/tools/write-tool.js +0 -81
@@ -1,59 +0,0 @@
1
- /**
2
- * Skill self-learning: decides whether a completed turn should
3
- * trigger skill creation or improvement instructions.
4
- */
5
- export interface SkillTurnResult {
6
- ok: boolean;
7
- /** Number of tool invocations in this turn */
8
- toolCallCount: number;
9
- /** Number of distinct tool names used */
10
- distinctToolCount: number;
11
- /** Was a multi-step orchestration (≥2 rounds) used? */
12
- multiStep: boolean;
13
- /** Did the turn involve a sidechain? */
14
- hasSidechain: boolean;
15
- /** Optional user feedback signal (positive/negative/none) */
16
- feedback?: "positive" | "negative" | null;
17
- /** Skill name if an existing skill was used */
18
- existingSkillName?: string | null;
19
- }
20
- export interface SkillCreateInstruction {
21
- type: "skill.create";
22
- /** Suggested skill name derived from tool usage pattern */
23
- suggestedName: string;
24
- /** Short description of what the skill does */
25
- description: string;
26
- /** Tool names involved */
27
- tools: string[];
28
- /** Number of orchestration steps */
29
- stepCount: number;
30
- }
31
- export interface SkillImproveInstruction {
32
- type: "skill.improve";
33
- /** Existing skill to improve */
34
- skillName: string;
35
- /** Reason for improvement */
36
- reason: string;
37
- }
38
- export type SkillInstruction = SkillCreateInstruction | SkillImproveInstruction;
39
- /**
40
- * Determine whether a completed turn should produce a skill instruction.
41
- *
42
- * A new skill is suggested when:
43
- * - The turn succeeded
44
- * - It involved multi-step orchestration
45
- * - It used ≥3 tool calls across ≥2 distinct tools
46
- * - No existing skill was already applied
47
- *
48
- * An improvement is suggested when:
49
- * - The turn used an existing skill but got negative feedback
50
- */
51
- export declare function shouldCreateSkill(result: SkillTurnResult): boolean;
52
- export declare function shouldImproveSkill(result: SkillTurnResult): boolean;
53
- /**
54
- * Build a skill instruction from a turn result, or null if none is warranted.
55
- */
56
- export declare function buildSkillInstruction(result: SkillTurnResult, context: {
57
- tools: string[];
58
- suggestedName?: string;
59
- }): SkillInstruction | null;
@@ -1,66 +0,0 @@
1
- /**
2
- * Skill self-learning: decides whether a completed turn should
3
- * trigger skill creation or improvement instructions.
4
- */
5
- // ── Decision logic ─────────────────────────────────────────────────
6
- /**
7
- * Minimum tool call count to consider a turn "complex enough"
8
- * to warrant creating a reusable skill.
9
- */
10
- const MIN_TOOL_CALLS_FOR_SKILL = 3;
11
- /**
12
- * Minimum distinct tools to suggest a new skill.
13
- */
14
- const MIN_DISTINCT_TOOLS_FOR_SKILL = 2;
15
- /**
16
- * Determine whether a completed turn should produce a skill instruction.
17
- *
18
- * A new skill is suggested when:
19
- * - The turn succeeded
20
- * - It involved multi-step orchestration
21
- * - It used ≥3 tool calls across ≥2 distinct tools
22
- * - No existing skill was already applied
23
- *
24
- * An improvement is suggested when:
25
- * - The turn used an existing skill but got negative feedback
26
- */
27
- export function shouldCreateSkill(result) {
28
- if (!result.ok)
29
- return false;
30
- if (result.existingSkillName)
31
- return false;
32
- if (!result.multiStep)
33
- return false;
34
- if (result.toolCallCount < MIN_TOOL_CALLS_FOR_SKILL)
35
- return false;
36
- if (result.distinctToolCount < MIN_DISTINCT_TOOLS_FOR_SKILL)
37
- return false;
38
- return true;
39
- }
40
- export function shouldImproveSkill(result) {
41
- if (!result.existingSkillName)
42
- return false;
43
- return result.feedback === "negative";
44
- }
45
- /**
46
- * Build a skill instruction from a turn result, or null if none is warranted.
47
- */
48
- export function buildSkillInstruction(result, context) {
49
- if (shouldImproveSkill(result)) {
50
- return {
51
- type: "skill.improve",
52
- skillName: result.existingSkillName,
53
- reason: "negative user feedback on existing skill execution",
54
- };
55
- }
56
- if (shouldCreateSkill(result)) {
57
- return {
58
- type: "skill.create",
59
- suggestedName: context.suggestedName ?? `auto-skill-${context.tools.slice(0, 3).join("-")}`,
60
- description: `Multi-step orchestration using ${context.tools.join(", ")}`,
61
- tools: context.tools,
62
- stepCount: result.toolCallCount,
63
- };
64
- }
65
- return null;
66
- }
@@ -1,98 +0,0 @@
1
- /**
2
- * Skill similarity — pure strategy for detecting near-duplicate skills
3
- * before creation and during curator consolidation reviews.
4
- *
5
- * Computes multi-signal similarity between skills:
6
- * 1. Tool-set Jaccard overlap (primary signal for auto-generated skills)
7
- * 2. Title/description cosine bigram similarity (complementary signal)
8
- * 3. Step-count proximity (minor signal for workflow complexity)
9
- *
10
- * No I/O — all functions are pure.
11
- */
12
- /** Minimal skill profile for similarity comparison. */
13
- export interface SkillSimilarityProfile {
14
- skillKey: string;
15
- title: string;
16
- tools: readonly string[];
17
- stepCount?: number;
18
- }
19
- /** Result of a pairwise similarity comparison. */
20
- export interface SimilarityScore {
21
- /** Overall similarity [0, 1]. */
22
- overall: number;
23
- /** Tool-set Jaccard index [0, 1]. */
24
- toolJaccard: number;
25
- /** Title bigram similarity [0, 1]. */
26
- titleSimilarity: number;
27
- /** Step-count proximity [0, 1]. */
28
- stepProximity: number;
29
- }
30
- /** A candidate detected as similar during pre-creation check. */
31
- export interface SimilarSkillMatch {
32
- existingSkillKey: string;
33
- score: SimilarityScore;
34
- }
35
- /** Policy for similarity thresholds. */
36
- export interface SkillSimilarityPolicy {
37
- /**
38
- * Overall similarity threshold to block creation and emit "improve"
39
- * instead. Default: 0.75.
40
- */
41
- blockCreationThreshold: number;
42
- /**
43
- * Overall similarity threshold to flag for curator review.
44
- * Default: 0.55.
45
- */
46
- curatorReviewThreshold: number;
47
- /** Weight of toolJaccard in overall score. Default: 0.60. */
48
- toolWeight: number;
49
- /** Weight of titleSimilarity in overall score. Default: 0.30. */
50
- titleWeight: number;
51
- /** Weight of stepProximity in overall score. Default: 0.10. */
52
- stepWeight: number;
53
- }
54
- export declare const DEFAULT_SKILL_SIMILARITY_POLICY: SkillSimilarityPolicy;
55
- /**
56
- * Compute Jaccard index between two tool sets.
57
- * Returns 0 if both sets are empty.
58
- */
59
- export declare function toolSetJaccard(toolsA: readonly string[], toolsB: readonly string[]): number;
60
- /**
61
- * Compute character-bigram similarity between two strings.
62
- * Uses Dice coefficient of bigram sets.
63
- */
64
- export declare function bigramSimilarity(a: string, b: string): number;
65
- /**
66
- * Compute step-count proximity [0, 1].
67
- * Returns 1 when counts are identical, decreases with difference.
68
- */
69
- export declare function stepCountProximity(stepsA: number | undefined, stepsB: number | undefined): number;
70
- /**
71
- * Compute overall similarity between two skill profiles.
72
- */
73
- export declare function computeSimilarity(a: SkillSimilarityProfile, b: SkillSimilarityProfile, policy?: Partial<SkillSimilarityPolicy>): SimilarityScore;
74
- /**
75
- * Check a new skill candidate against existing skills for similarity.
76
- *
77
- * Returns all existing skills above curatorReviewThreshold, sorted
78
- * by descending similarity. The caller should:
79
- * - Block creation if any match ≥ blockCreationThreshold (emit improve instead)
80
- * - Tag for curator review if match ≥ curatorReviewThreshold
81
- */
82
- export declare function findSimilarSkills(newSkill: SkillSimilarityProfile, existingSkills: readonly SkillSimilarityProfile[], policy?: Partial<SkillSimilarityPolicy>): SimilarSkillMatch[];
83
- /**
84
- * Determine creation decision based on similarity matches.
85
- */
86
- export type SimilarityDecision = {
87
- action: "create";
88
- reason: string;
89
- } | {
90
- action: "improve";
91
- targetSkillKey: string;
92
- reason: string;
93
- } | {
94
- action: "flag-for-review";
95
- targetSkillKey: string;
96
- reason: string;
97
- };
98
- export declare function decideSimilarityAction(matches: readonly SimilarSkillMatch[], policy?: Partial<SkillSimilarityPolicy>): SimilarityDecision;
@@ -1,131 +0,0 @@
1
- /**
2
- * Skill similarity — pure strategy for detecting near-duplicate skills
3
- * before creation and during curator consolidation reviews.
4
- *
5
- * Computes multi-signal similarity between skills:
6
- * 1. Tool-set Jaccard overlap (primary signal for auto-generated skills)
7
- * 2. Title/description cosine bigram similarity (complementary signal)
8
- * 3. Step-count proximity (minor signal for workflow complexity)
9
- *
10
- * No I/O — all functions are pure.
11
- */
12
- export const DEFAULT_SKILL_SIMILARITY_POLICY = {
13
- blockCreationThreshold: 0.75,
14
- curatorReviewThreshold: 0.55,
15
- toolWeight: 0.60,
16
- titleWeight: 0.30,
17
- stepWeight: 0.10,
18
- };
19
- // ── Core similarity functions ──────────────────────────────────────
20
- /**
21
- * Compute Jaccard index between two tool sets.
22
- * Returns 0 if both sets are empty.
23
- */
24
- export function toolSetJaccard(toolsA, toolsB) {
25
- const setA = new Set(toolsA.map((t) => t.toLowerCase()));
26
- const setB = new Set(toolsB.map((t) => t.toLowerCase()));
27
- if (setA.size === 0 && setB.size === 0)
28
- return 0;
29
- let intersection = 0;
30
- for (const t of setA) {
31
- if (setB.has(t))
32
- intersection++;
33
- }
34
- const union = setA.size + setB.size - intersection;
35
- return union === 0 ? 0 : intersection / union;
36
- }
37
- /**
38
- * Compute character-bigram similarity between two strings.
39
- * Uses Dice coefficient of bigram sets.
40
- */
41
- export function bigramSimilarity(a, b) {
42
- const bigramsA = extractBigrams(a.toLowerCase());
43
- const bigramsB = extractBigrams(b.toLowerCase());
44
- if (bigramsA.size === 0 && bigramsB.size === 0)
45
- return 0;
46
- if (bigramsA.size === 0 || bigramsB.size === 0)
47
- return 0;
48
- let intersection = 0;
49
- for (const bg of bigramsA) {
50
- if (bigramsB.has(bg))
51
- intersection++;
52
- }
53
- // Dice coefficient = 2 * |intersection| / (|A| + |B|)
54
- return (2 * intersection) / (bigramsA.size + bigramsB.size);
55
- }
56
- function extractBigrams(s) {
57
- const bigrams = new Set();
58
- const normalized = s.replace(/[^a-z0-9\u4e00-\u9fff]/g, " ").trim();
59
- for (let i = 0; i < normalized.length - 1; i++) {
60
- bigrams.add(normalized.slice(i, i + 2));
61
- }
62
- return bigrams;
63
- }
64
- /**
65
- * Compute step-count proximity [0, 1].
66
- * Returns 1 when counts are identical, decreases with difference.
67
- */
68
- export function stepCountProximity(stepsA, stepsB) {
69
- if (stepsA == null || stepsB == null)
70
- return 0.5; // neutral if unknown
71
- if (stepsA === 0 && stepsB === 0)
72
- return 1;
73
- const diff = Math.abs(stepsA - stepsB);
74
- const max = Math.max(stepsA, stepsB);
75
- return 1 - diff / max;
76
- }
77
- // ── Composite similarity ───────────────────────────────────────────
78
- /**
79
- * Compute overall similarity between two skill profiles.
80
- */
81
- export function computeSimilarity(a, b, policy) {
82
- const resolved = { ...DEFAULT_SKILL_SIMILARITY_POLICY, ...policy };
83
- const toolJaccard = toolSetJaccard(a.tools, b.tools);
84
- const titleSimilarity = bigramSimilarity(a.title, b.title);
85
- const stepProximity = stepCountProximity(a.stepCount, b.stepCount);
86
- const overall = resolved.toolWeight * toolJaccard +
87
- resolved.titleWeight * titleSimilarity +
88
- resolved.stepWeight * stepProximity;
89
- return { overall, toolJaccard, titleSimilarity, stepProximity };
90
- }
91
- // ── Pre-creation duplicate check ───────────────────────────────────
92
- /**
93
- * Check a new skill candidate against existing skills for similarity.
94
- *
95
- * Returns all existing skills above curatorReviewThreshold, sorted
96
- * by descending similarity. The caller should:
97
- * - Block creation if any match ≥ blockCreationThreshold (emit improve instead)
98
- * - Tag for curator review if match ≥ curatorReviewThreshold
99
- */
100
- export function findSimilarSkills(newSkill, existingSkills, policy) {
101
- const resolved = { ...DEFAULT_SKILL_SIMILARITY_POLICY, ...policy };
102
- const matches = [];
103
- for (const existing of existingSkills) {
104
- if (existing.skillKey === newSkill.skillKey)
105
- continue; // skip self
106
- const score = computeSimilarity(newSkill, existing, resolved);
107
- if (score.overall >= resolved.curatorReviewThreshold) {
108
- matches.push({ existingSkillKey: existing.skillKey, score });
109
- }
110
- }
111
- return matches.sort((a, b) => b.score.overall - a.score.overall);
112
- }
113
- export function decideSimilarityAction(matches, policy) {
114
- const resolved = { ...DEFAULT_SKILL_SIMILARITY_POLICY, ...policy };
115
- if (matches.length === 0) {
116
- return { action: "create", reason: "no similar skills found" };
117
- }
118
- const top = matches[0];
119
- if (top.score.overall >= resolved.blockCreationThreshold) {
120
- return {
121
- action: "improve",
122
- targetSkillKey: top.existingSkillKey,
123
- reason: `similarity ${(top.score.overall * 100).toFixed(0)}% ≥ creation threshold ${(resolved.blockCreationThreshold * 100).toFixed(0)}% (tool overlap: ${(top.score.toolJaccard * 100).toFixed(0)}%)`,
124
- };
125
- }
126
- return {
127
- action: "flag-for-review",
128
- targetSkillKey: top.existingSkillKey,
129
- reason: `similarity ${(top.score.overall * 100).toFixed(0)}% between review and creation thresholds`,
130
- };
131
- }
@@ -1,73 +0,0 @@
1
- /**
2
- * StreamingToolExecutor — Executes tool calls as they arrive during LLM streaming.
3
- *
4
- * Aligned with Claude Code's StreamingToolExecutor pattern:
5
- * - As each complete tool_use block arrives during streaming, immediately dispatch execution
6
- * - Don't wait for the full LLM response to finish before starting tool execution
7
- * - Results queue up and can be collected at any time
8
- *
9
- * This reduces perceived latency by overlapping LLM generation time with tool execution time.
10
- */
11
- export interface StreamingToolCall {
12
- id: string;
13
- function: {
14
- name: string;
15
- arguments: string;
16
- };
17
- }
18
- export interface StreamingToolResult<T = unknown> {
19
- toolCallId: string;
20
- toolName: string;
21
- result: T;
22
- ok: boolean;
23
- startedAt: number;
24
- completedAt: number;
25
- error?: string;
26
- }
27
- export interface StreamingToolExecutorConfig {
28
- /** Maximum concurrent tool executions (default: 8) */
29
- maxConcurrency: number;
30
- /** Abort signal for cancellation */
31
- abortSignal?: AbortSignal;
32
- }
33
- export type ToolExecutorFn<T = unknown> = (toolCall: StreamingToolCall, abortSignal?: AbortSignal) => Promise<T>;
34
- /**
35
- * Streaming tool executor that dispatches tool calls immediately as they complete
36
- * during LLM streaming output, rather than waiting for the full response.
37
- *
38
- * Usage:
39
- * ```ts
40
- * const executor = createStreamingToolExecutor(executeFn, { maxConcurrency: 4 });
41
- * // During streaming, as each tool block completes:
42
- * executor.addTool(toolCall);
43
- * // Periodically collect completed results:
44
- * const results = executor.getCompletedResults();
45
- * // After streaming ends, wait for all remaining:
46
- * const allResults = await executor.flush();
47
- * ```
48
- */
49
- export interface StreamingToolExecutor<T = unknown> {
50
- /** Add a tool call for immediate execution. Returns false if at capacity. */
51
- addTool(toolCall: StreamingToolCall): boolean;
52
- /** Get results that have completed since last call (non-blocking). */
53
- getCompletedResults(): StreamingToolResult<T>[];
54
- /** Wait for all pending tool calls to complete and return all results. */
55
- flush(): Promise<StreamingToolResult<T>[]>;
56
- /** Number of currently executing tool calls. */
57
- readonly pendingCount: number;
58
- /** Total number of tool calls dispatched. */
59
- readonly dispatchedCount: number;
60
- /** Whether the executor has been aborted. */
61
- readonly aborted: boolean;
62
- }
63
- export declare function createStreamingToolExecutor<T = unknown>(executeFn: ToolExecutorFn<T>, config?: Partial<StreamingToolExecutorConfig>): StreamingToolExecutor<T>;
64
- /**
65
- * Determine if a tool call can be dispatched immediately during streaming
66
- * based on its manifest properties.
67
- */
68
- export declare function canDispatchDuringStreaming(toolCall: StreamingToolCall, manifest?: {
69
- approvalMode?: "user-confirm" | "pre-authorized";
70
- requiresApproval?: boolean;
71
- serialOnly?: boolean;
72
- parallelSafe?: boolean;
73
- }): boolean;
@@ -1,96 +0,0 @@
1
- /**
2
- * StreamingToolExecutor — Executes tool calls as they arrive during LLM streaming.
3
- *
4
- * Aligned with Claude Code's StreamingToolExecutor pattern:
5
- * - As each complete tool_use block arrives during streaming, immediately dispatch execution
6
- * - Don't wait for the full LLM response to finish before starting tool execution
7
- * - Results queue up and can be collected at any time
8
- *
9
- * This reduces perceived latency by overlapping LLM generation time with tool execution time.
10
- */
11
- export function createStreamingToolExecutor(executeFn, config = {}) {
12
- const maxConcurrency = Math.max(1, config.maxConcurrency ?? 8);
13
- const abortSignal = config.abortSignal;
14
- const pending = [];
15
- const completedQueue = [];
16
- let dispatchedCount = 0;
17
- let aborted = false;
18
- if (abortSignal) {
19
- abortSignal.addEventListener("abort", () => { aborted = true; }, { once: true });
20
- }
21
- function addTool(toolCall) {
22
- if (aborted)
23
- return false;
24
- if (pending.length >= maxConcurrency)
25
- return false;
26
- dispatchedCount += 1;
27
- const startedAt = Date.now();
28
- const entry = {
29
- toolCallId: toolCall.id,
30
- toolName: toolCall.function.name,
31
- startedAt,
32
- promise: executeFn(toolCall, abortSignal)
33
- .then((result) => ({
34
- toolCallId: toolCall.id,
35
- toolName: toolCall.function.name,
36
- result,
37
- ok: true,
38
- startedAt,
39
- completedAt: Date.now(),
40
- }))
41
- .catch((err) => ({
42
- toolCallId: toolCall.id,
43
- toolName: toolCall.function.name,
44
- result: undefined,
45
- ok: false,
46
- startedAt,
47
- completedAt: Date.now(),
48
- error: err instanceof Error ? err.message : String(err),
49
- }))
50
- .then((result) => {
51
- // Move from pending to completed queue
52
- const idx = pending.indexOf(entry);
53
- if (idx >= 0)
54
- pending.splice(idx, 1);
55
- completedQueue.push(result);
56
- return result;
57
- }),
58
- };
59
- pending.push(entry);
60
- return true;
61
- }
62
- function getCompletedResults() {
63
- const results = completedQueue.splice(0);
64
- return results;
65
- }
66
- async function flush() {
67
- if (pending.length > 0) {
68
- await Promise.allSettled(pending.map((e) => e.promise));
69
- }
70
- return completedQueue.splice(0);
71
- }
72
- return {
73
- addTool,
74
- getCompletedResults,
75
- flush,
76
- get pendingCount() { return pending.length; },
77
- get dispatchedCount() { return dispatchedCount; },
78
- get aborted() { return aborted; },
79
- };
80
- }
81
- /**
82
- * Determine if a tool call can be dispatched immediately during streaming
83
- * based on its manifest properties.
84
- */
85
- export function canDispatchDuringStreaming(toolCall, manifest) {
86
- if (!manifest)
87
- return false;
88
- // Cannot dispatch during streaming if it requires user approval
89
- if (manifest.approvalMode === "user-confirm" || manifest.requiresApproval)
90
- return false;
91
- // Cannot dispatch if explicitly serial-only
92
- if (manifest.serialOnly)
93
- return false;
94
- // Safe to dispatch during streaming
95
- return true;
96
- }