@owlmeans/llm 0.1.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +193 -0
- package/agent-meta/instructions/llm.instructions.md +66 -0
- package/agent-meta/manifest.json +23 -0
- package/agent-meta/skills/llm/SKILL.md +121 -0
- package/build/consts.d.ts +67 -0
- package/build/consts.d.ts.map +1 -0
- package/build/consts.js +76 -0
- package/build/consts.js.map +1 -0
- package/build/errors.d.ts +33 -0
- package/build/errors.d.ts.map +1 -0
- package/build/errors.js +52 -0
- package/build/errors.js.map +1 -0
- package/build/execution/index.d.ts +4 -0
- package/build/execution/index.d.ts.map +1 -0
- package/build/execution/index.js +3 -0
- package/build/execution/index.js.map +1 -0
- package/build/execution/service.d.ts +21 -0
- package/build/execution/service.d.ts.map +1 -0
- package/build/execution/service.js +129 -0
- package/build/execution/service.js.map +1 -0
- package/build/execution/types.d.ts +119 -0
- package/build/execution/types.d.ts.map +1 -0
- package/build/execution/types.js +2 -0
- package/build/execution/types.js.map +1 -0
- package/build/execution/utils.d.ts +28 -0
- package/build/execution/utils.d.ts.map +1 -0
- package/build/execution/utils.js +60 -0
- package/build/execution/utils.js.map +1 -0
- package/build/helpers/index.d.ts +5 -0
- package/build/helpers/index.d.ts.map +1 -0
- package/build/helpers/index.js +5 -0
- package/build/helpers/index.js.map +1 -0
- package/build/helpers/json.d.ts +24 -0
- package/build/helpers/json.d.ts.map +1 -0
- package/build/helpers/json.js +119 -0
- package/build/helpers/json.js.map +1 -0
- package/build/helpers/messages.d.ts +10 -0
- package/build/helpers/messages.d.ts.map +1 -0
- package/build/helpers/messages.js +9 -0
- package/build/helpers/messages.js.map +1 -0
- package/build/helpers/retry.d.ts +18 -0
- package/build/helpers/retry.d.ts.map +1 -0
- package/build/helpers/retry.js +57 -0
- package/build/helpers/retry.js.map +1 -0
- package/build/helpers/spectate.d.ts +8 -0
- package/build/helpers/spectate.d.ts.map +1 -0
- package/build/helpers/spectate.js +54 -0
- package/build/helpers/spectate.js.map +1 -0
- package/build/index.d.ts +13 -0
- package/build/index.d.ts.map +1 -0
- package/build/index.js +11 -0
- package/build/index.js.map +1 -0
- package/build/model.d.ts +12 -0
- package/build/model.d.ts.map +1 -0
- package/build/model.js +297 -0
- package/build/model.js.map +1 -0
- package/build/plugins/anthropic.d.ts +4 -0
- package/build/plugins/anthropic.d.ts.map +1 -0
- package/build/plugins/anthropic.js +86 -0
- package/build/plugins/anthropic.js.map +1 -0
- package/build/plugins/compatible.d.ts +18 -0
- package/build/plugins/compatible.d.ts.map +1 -0
- package/build/plugins/compatible.js +54 -0
- package/build/plugins/compatible.js.map +1 -0
- package/build/plugins/export.d.ts +6 -0
- package/build/plugins/export.d.ts.map +1 -0
- package/build/plugins/export.js +5 -0
- package/build/plugins/export.js.map +1 -0
- package/build/plugins/index.d.ts +18 -0
- package/build/plugins/index.d.ts.map +1 -0
- package/build/plugins/index.js +42 -0
- package/build/plugins/index.js.map +1 -0
- package/build/plugins/openai.d.ts +28 -0
- package/build/plugins/openai.d.ts.map +1 -0
- package/build/plugins/openai.js +89 -0
- package/build/plugins/openai.js.map +1 -0
- package/build/plugins/types.d.ts +80 -0
- package/build/plugins/types.d.ts.map +1 -0
- package/build/plugins/types.js +2 -0
- package/build/plugins/types.js.map +1 -0
- package/build/plugins/utils.d.ts +27 -0
- package/build/plugins/utils.d.ts.map +1 -0
- package/build/plugins/utils.js +33 -0
- package/build/plugins/utils.js.map +1 -0
- package/build/service.d.ts +24 -0
- package/build/service.d.ts.map +1 -0
- package/build/service.js +95 -0
- package/build/service.js.map +1 -0
- package/build/types.d.ts +190 -0
- package/build/types.d.ts.map +1 -0
- package/build/types.js +2 -0
- package/build/types.js.map +1 -0
- package/build/utils/config.d.ts +13 -0
- package/build/utils/config.d.ts.map +1 -0
- package/build/utils/config.js +15 -0
- package/build/utils/config.js.map +1 -0
- package/build/utils/null-report.d.ts +36 -0
- package/build/utils/null-report.d.ts.map +1 -0
- package/build/utils/null-report.js +84 -0
- package/build/utils/null-report.js.map +1 -0
- package/build/utils/prompt.d.ts +15 -0
- package/build/utils/prompt.d.ts.map +1 -0
- package/build/utils/prompt.js +45 -0
- package/build/utils/prompt.js.map +1 -0
- package/build/utils/schema.d.ts +20 -0
- package/build/utils/schema.d.ts.map +1 -0
- package/build/utils/schema.js +28 -0
- package/build/utils/schema.js.map +1 -0
- package/build/utils/stream.d.ts +22 -0
- package/build/utils/stream.d.ts.map +1 -0
- package/build/utils/stream.js +54 -0
- package/build/utils/stream.js.map +1 -0
- package/package.json +65 -0
- package/src/consts.ts +89 -0
- package/src/errors.ts +65 -0
- package/src/execution/index.ts +4 -0
- package/src/execution/service.ts +185 -0
- package/src/execution/types.ts +139 -0
- package/src/execution/utils.ts +79 -0
- package/src/helpers/index.ts +5 -0
- package/src/helpers/json.ts +117 -0
- package/src/helpers/messages.ts +12 -0
- package/src/helpers/retry.ts +59 -0
- package/src/helpers/spectate.ts +67 -0
- package/src/index.ts +13 -0
- package/src/model.ts +379 -0
- package/src/plugins/anthropic.ts +97 -0
- package/src/plugins/compatible.ts +62 -0
- package/src/plugins/export.ts +6 -0
- package/src/plugins/index.ts +53 -0
- package/src/plugins/openai.ts +108 -0
- package/src/plugins/types.ts +92 -0
- package/src/plugins/utils.ts +38 -0
- package/src/service.ts +125 -0
- package/src/types.ts +214 -0
- package/src/utils/config.ts +19 -0
- package/src/utils/null-report.ts +126 -0
- package/src/utils/prompt.ts +46 -0
- package/src/utils/schema.ts +35 -0
- package/src/utils/stream.ts +58 -0
- package/tests/context.ts +110 -0
- package/tests/execution.spec.ts +200 -0
- package/tests/helpers.spec.ts +192 -0
- package/tests/internals.spec.ts +141 -0
- package/tests/model.spec.ts +116 -0
- package/tests/plugins.spec.ts +227 -0
- package/tsconfig.json +19 -0
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
import { describe, expect, test } from 'bun:test'
|
|
2
|
+
import { ChatAnthropic } from '@langchain/anthropic'
|
|
3
|
+
import { ChatOpenAI } from '@langchain/openai'
|
|
4
|
+
import { BadRequestError } from '@anthropic-ai/sdk'
|
|
5
|
+
import { ModelProvider, StructuredMode } from '@owlmeans/llm-common'
|
|
6
|
+
import {
|
|
7
|
+
anthropicPlugin, compatiblePlugin, makeLlmService, openAiPlugin, pluginFor, pluginOf,
|
|
8
|
+
registerLlmPlugin, resolvePlugin,
|
|
9
|
+
} from '@owlmeans/llm'
|
|
10
|
+
import type { LlmPlugin, ModelConfig } from '@owlmeans/llm'
|
|
11
|
+
import { offlineConfigs, Role } from './context.js'
|
|
12
|
+
|
|
13
|
+
const build = (plugin: LlmPlugin, config: Partial<ModelConfig> = {}) =>
|
|
14
|
+
plugin.build({
|
|
15
|
+
alias: 'spec', secret: 'sk-test', callbacks: [],
|
|
16
|
+
config: { alias: 'spec', ...config } as ModelConfig,
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
describe('@owlmeans/llm — plugin resolution', () => {
|
|
20
|
+
test('resolves by the config provider', () => {
|
|
21
|
+
expect(resolvePlugin({ provider: ModelProvider.Anthropic }).type).toBe(ModelProvider.Anthropic)
|
|
22
|
+
expect(resolvePlugin({ provider: ModelProvider.OpenAI }).type).toBe(ModelProvider.OpenAI)
|
|
23
|
+
expect(resolvePlugin({ provider: ModelProvider.Compatible }).type).toBe(ModelProvider.Compatible)
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
// A refined model instance is rebuilt from lc_kwargs and may lose its metadata, so the
|
|
27
|
+
// fallback path must still land on a plugin — the CONSERVATIVE one of the family.
|
|
28
|
+
test('falls back to the instance family, preferring the conservative member', () => {
|
|
29
|
+
const anthropic = build(anthropicPlugin, { model: 'claude-haiku-4-5-20251001' })
|
|
30
|
+
const openai = build(openAiPlugin, { model: 'gpt-4.1-mini' })
|
|
31
|
+
|
|
32
|
+
expect(pluginFor(anthropic)?.type).toBe(ModelProvider.Anthropic)
|
|
33
|
+
// Both openai and compatible own a ChatOpenAI; compatible (tool-calling) wins.
|
|
34
|
+
expect(pluginFor(openai)?.type).toBe(ModelProvider.Compatible)
|
|
35
|
+
expect(resolvePlugin(undefined, openai).type).toBe(ModelProvider.Compatible)
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
test('an unknown provider with no model instance is an error, not a silent default', () => {
|
|
39
|
+
expect(() => resolvePlugin({ provider: 'no-such-provider' })).toThrow()
|
|
40
|
+
expect(pluginOf('no-such-provider')).toBeUndefined()
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
test('a custom plugin can be registered and then resolved', () => {
|
|
44
|
+
const custom: LlmPlugin = {
|
|
45
|
+
...openAiPlugin, type: 'spec-custom', structuredMode: () => StructuredMode.Native,
|
|
46
|
+
}
|
|
47
|
+
registerLlmPlugin(custom)
|
|
48
|
+
expect(resolvePlugin({ provider: 'spec-custom' }).type).toBe('spec-custom')
|
|
49
|
+
// Registered last, so it never shadows the built-ins on instance lookup.
|
|
50
|
+
expect(pluginFor(build(openAiPlugin, { model: 'gpt-4.1-mini' }))?.type)
|
|
51
|
+
.toBe(ModelProvider.Compatible)
|
|
52
|
+
})
|
|
53
|
+
})
|
|
54
|
+
|
|
55
|
+
describe('@owlmeans/llm — structured-output mode per provider', () => {
|
|
56
|
+
test('anthropic is always tool-calling and ignores the config flag', () => {
|
|
57
|
+
expect(anthropicPlugin.structuredMode({ alias: 'a' })).toBe(StructuredMode.Tool)
|
|
58
|
+
expect(anthropicPlugin.structuredMode({ alias: 'a', structuredOutput: true })).toBe(StructuredMode.Tool)
|
|
59
|
+
})
|
|
60
|
+
|
|
61
|
+
test('proprietary openai defaults to native, compatible defaults to tool-calling', () => {
|
|
62
|
+
expect(openAiPlugin.structuredMode({ alias: 'a' })).toBe(StructuredMode.Native)
|
|
63
|
+
expect(compatiblePlugin.structuredMode({ alias: 'a' })).toBe(StructuredMode.Tool)
|
|
64
|
+
})
|
|
65
|
+
|
|
66
|
+
test('the config flag overrides both defaults', () => {
|
|
67
|
+
expect(openAiPlugin.structuredMode({ alias: 'a', structuredOutput: false })).toBe(StructuredMode.Tool)
|
|
68
|
+
expect(compatiblePlugin.structuredMode({ alias: 'a', structuredOutput: true })).toBe(StructuredMode.Native)
|
|
69
|
+
})
|
|
70
|
+
|
|
71
|
+
test('tool_choice uses the spelling each provider accepts', () => {
|
|
72
|
+
expect(anthropicPlugin.toolChoice('extract')).toEqual({ type: 'tool', name: 'extract' })
|
|
73
|
+
expect(openAiPlugin.toolChoice('extract')).toEqual({ type: 'function', function: { name: 'extract' } })
|
|
74
|
+
expect(compatiblePlugin.toolChoice('extract')).toEqual({ type: 'function', function: { name: 'extract' } })
|
|
75
|
+
})
|
|
76
|
+
|
|
77
|
+
test('only the OpenAI family offers a native response_format', () => {
|
|
78
|
+
expect(anthropicPlugin.responseFormat).toBeUndefined()
|
|
79
|
+
expect(openAiPlugin.responseFormat?.('extract', { type: 'object' })).toEqual({
|
|
80
|
+
type: 'json_schema',
|
|
81
|
+
json_schema: { name: 'extract', schema: { type: 'object' }, strict: false },
|
|
82
|
+
})
|
|
83
|
+
})
|
|
84
|
+
})
|
|
85
|
+
|
|
86
|
+
describe('@owlmeans/llm — client construction', () => {
|
|
87
|
+
test('the resolved config (with its applied default) is readable back off the client', () => {
|
|
88
|
+
const model = build(compatiblePlugin, {
|
|
89
|
+
provider: ModelProvider.Compatible, baseUrl: 'https://openrouter.ai/api/v1',
|
|
90
|
+
})
|
|
91
|
+
const config = (model as unknown as { metadata: { config: ModelConfig } }).metadata.config
|
|
92
|
+
expect(config.provider).toBe(ModelProvider.Compatible)
|
|
93
|
+
expect(config.model).toBeString()
|
|
94
|
+
})
|
|
95
|
+
|
|
96
|
+
test('compatible forwards the aggregator request fields', () => {
|
|
97
|
+
const model = build(compatiblePlugin, {
|
|
98
|
+
model: 'z-ai/glm-5.1', baseUrl: 'https://openrouter.ai/api/v1',
|
|
99
|
+
reasoning: { max_tokens: 1024 },
|
|
100
|
+
}) as ChatOpenAI
|
|
101
|
+
const kwargs = model.lc_kwargs as { modelKwargs?: Record<string, unknown>, configuration?: { baseURL?: string } }
|
|
102
|
+
expect(kwargs.modelKwargs?.provider).toEqual({ require_parameters: true })
|
|
103
|
+
expect(kwargs.modelKwargs?.reasoning).toEqual({ max_tokens: 1024 })
|
|
104
|
+
expect(kwargs.configuration?.baseURL).toBe('https://openrouter.ai/api/v1')
|
|
105
|
+
})
|
|
106
|
+
|
|
107
|
+
test('compatible encodes the HuggingFace serving provider and billing header', () => {
|
|
108
|
+
const model = build(compatiblePlugin, {
|
|
109
|
+
model: 'Qwen/Qwen3-235B', baseUrl: 'https://router.huggingface.co/v1',
|
|
110
|
+
inferenceProvider: 'together', organization: 'acme',
|
|
111
|
+
}) as ChatOpenAI
|
|
112
|
+
const kwargs = model.lc_kwargs as {
|
|
113
|
+
model?: string, configuration?: { defaultHeaders?: Record<string, string> }
|
|
114
|
+
}
|
|
115
|
+
expect(kwargs.model).toBe('Qwen/Qwen3-235B:together')
|
|
116
|
+
expect(kwargs.configuration?.defaultHeaders?.['X-HF-Bill-To']).toBe('acme')
|
|
117
|
+
})
|
|
118
|
+
|
|
119
|
+
test('openai switches the gpt-5 family to the Responses API and omits sampling knobs', () => {
|
|
120
|
+
const responses = build(openAiPlugin, { model: 'gpt-5.4-mini' }) as ChatOpenAI
|
|
121
|
+
const chat = build(openAiPlugin, { model: 'gpt-4.1-mini' }) as ChatOpenAI
|
|
122
|
+
expect((responses.lc_kwargs as { useResponsesApi?: boolean }).useResponsesApi).toBe(true)
|
|
123
|
+
expect((responses.lc_kwargs as { topP?: number }).topP).toBeUndefined()
|
|
124
|
+
expect((chat.lc_kwargs as { useResponsesApi?: boolean }).useResponsesApi).toBeUndefined()
|
|
125
|
+
expect((chat.lc_kwargs as { topP?: number }).topP).toBe(0.8)
|
|
126
|
+
})
|
|
127
|
+
|
|
128
|
+
// Anthropic rejects temperature and top_p in the same request.
|
|
129
|
+
test('anthropic never sends temperature and topP together', () => {
|
|
130
|
+
const both = build(anthropicPlugin, { temperature: 0.7, topP: 0.9 }) as ChatAnthropic
|
|
131
|
+
expect(both.temperature).toBe(0.7)
|
|
132
|
+
expect(both.topP).toBeUndefined()
|
|
133
|
+
|
|
134
|
+
const topPOnly = build(anthropicPlugin, { topP: 0.9 }) as ChatAnthropic
|
|
135
|
+
expect(topPOnly.topP).toBe(0.9)
|
|
136
|
+
})
|
|
137
|
+
})
|
|
138
|
+
|
|
139
|
+
describe('@owlmeans/llm — retry escalation behaviour', () => {
|
|
140
|
+
test('refine doubles the output budget per attempt and clamps to the cap', () => {
|
|
141
|
+
const base = build(openAiPlugin, { model: 'gpt-4.1-mini', maxTokens: 1000 })
|
|
142
|
+
expect((openAiPlugin.refine({ base, attempt: 0, maxOutputCap: 5000 }) as ChatOpenAI).maxTokens).toBe(1000)
|
|
143
|
+
expect((openAiPlugin.refine({ base, attempt: 2, maxOutputCap: 5000 }) as ChatOpenAI).maxTokens).toBe(4000)
|
|
144
|
+
expect((openAiPlugin.refine({ base, attempt: 8, maxOutputCap: 5000 }) as ChatOpenAI).maxTokens).toBe(5000)
|
|
145
|
+
})
|
|
146
|
+
|
|
147
|
+
// Extra budget must become visible output, not more hidden reasoning.
|
|
148
|
+
test('refine shrinks an absolute reasoning cap as the attempt grows', () => {
|
|
149
|
+
const base = build(compatiblePlugin, {
|
|
150
|
+
model: 'z-ai/glm-5.1', baseUrl: 'https://openrouter.ai/api/v1', reasoning: { max_tokens: 4096 },
|
|
151
|
+
})
|
|
152
|
+
const read = (model: unknown) =>
|
|
153
|
+
((model as ChatOpenAI).lc_kwargs as { modelKwargs?: { reasoning?: { max_tokens?: number } } })
|
|
154
|
+
.modelKwargs?.reasoning?.max_tokens
|
|
155
|
+
|
|
156
|
+
expect(read(compatiblePlugin.refine({ base, attempt: 0, maxOutputCap: 32000 }))).toBe(4096)
|
|
157
|
+
expect(read(compatiblePlugin.refine({ base, attempt: 2, maxOutputCap: 32000 }))).toBe(1024)
|
|
158
|
+
expect(read(compatiblePlugin.refine({ base, attempt: 9, maxOutputCap: 32000 }))).toBe(256)
|
|
159
|
+
})
|
|
160
|
+
|
|
161
|
+
test('the model families are distinct, which is what gates cross-provider fallback', () => {
|
|
162
|
+
expect(openAiPlugin.family).toBe(compatiblePlugin.family)
|
|
163
|
+
expect(anthropicPlugin.family).not.toBe(openAiPlugin.family)
|
|
164
|
+
})
|
|
165
|
+
})
|
|
166
|
+
|
|
167
|
+
describe('@owlmeans/llm — prompt caching', () => {
|
|
168
|
+
test('anthropic marks up to the requested number of leading messages', () => {
|
|
169
|
+
const model = build(anthropicPlugin, { model: 'claude-haiku-4-5-20251001' })
|
|
170
|
+
const msgs = [
|
|
171
|
+
{ role: 'system' as const, content: 'a' },
|
|
172
|
+
{ role: 'user' as const, content: 'b' },
|
|
173
|
+
{ role: 'user' as const, content: 'c' },
|
|
174
|
+
]
|
|
175
|
+
expect(anthropicPlugin.patchCache?.(msgs, { model, useCache: true, cacheMax: 2 })).toBe(true)
|
|
176
|
+
expect(msgs[0]!.content).toEqual([{ type: 'text', text: 'a', cache_control: { type: 'ephemeral' } }])
|
|
177
|
+
expect(msgs[1]!.content).toEqual([{ type: 'text', text: 'b', cache_control: { type: 'ephemeral' } }])
|
|
178
|
+
expect(msgs[2]!.content).toBe('c')
|
|
179
|
+
})
|
|
180
|
+
|
|
181
|
+
test('caching is a no-op when not requested, and for providers without it', () => {
|
|
182
|
+
const model = build(anthropicPlugin, { model: 'claude-haiku-4-5-20251001' })
|
|
183
|
+
const msgs = [{ role: 'user' as const, content: 'a' }]
|
|
184
|
+
expect(anthropicPlugin.patchCache?.(msgs, { model, useCache: false, cacheMax: 4 })).toBe(false)
|
|
185
|
+
expect(msgs[0]!.content).toBe('a')
|
|
186
|
+
expect(openAiPlugin.patchCache).toBeUndefined()
|
|
187
|
+
})
|
|
188
|
+
})
|
|
189
|
+
|
|
190
|
+
describe('@owlmeans/llm — fatal error classification', () => {
|
|
191
|
+
test('a malformed anthropic request aborts the retry loop', () => {
|
|
192
|
+
const bad = new BadRequestError(400, { type: 'error' }, 'max_tokens too large', new Headers())
|
|
193
|
+
expect(anthropicPlugin.isFatal?.(bad)).toBe(bad)
|
|
194
|
+
expect(anthropicPlugin.isFatal?.(new Error('transient'))).toBeNull()
|
|
195
|
+
})
|
|
196
|
+
})
|
|
197
|
+
|
|
198
|
+
describe('@owlmeans/llm — service', () => {
|
|
199
|
+
test('resolves a model by alias, memoizes it, and honours createNew', () => {
|
|
200
|
+
const service = makeLlmService({ models: offlineConfigs }, 'spec-llm-memo')
|
|
201
|
+
const first = service.getModel(Role.Analyst)
|
|
202
|
+
expect(service.getModel(Role.Analyst)).toBe(first)
|
|
203
|
+
expect(service.getModel(Role.Analyst, {}, true)).not.toBe(first)
|
|
204
|
+
})
|
|
205
|
+
|
|
206
|
+
test('an override participates in the cache key', () => {
|
|
207
|
+
const service = makeLlmService({ models: offlineConfigs }, 'spec-llm-override')
|
|
208
|
+
const plain = service.getModel(Role.Analyst)
|
|
209
|
+
const hot = service.getModel(Role.Analyst, { temperature: 0.9 })
|
|
210
|
+
expect(hot).not.toBe(plain)
|
|
211
|
+
expect((hot as ChatOpenAI).temperature).toBe(0.9)
|
|
212
|
+
})
|
|
213
|
+
|
|
214
|
+
test('a preset alias is inherited, and a fallback is attached off-enumeration', () => {
|
|
215
|
+
const service = makeLlmService({ models: offlineConfigs }, 'spec-llm-preset')
|
|
216
|
+
const picker = service.getModel(Role.Picker)
|
|
217
|
+
const fallback = (picker as unknown as { __fallbackModel?: ChatOpenAI }).__fallbackModel
|
|
218
|
+
expect(fallback).toBeDefined()
|
|
219
|
+
expect((fallback!.lc_kwargs as { model?: string }).model).toBe('some/stronger-model')
|
|
220
|
+
expect(Object.keys(picker)).not.toContain('__fallbackModel')
|
|
221
|
+
})
|
|
222
|
+
|
|
223
|
+
test('an unknown alias is reported as a misconfiguration', () => {
|
|
224
|
+
const service = makeLlmService({ models: offlineConfigs }, 'spec-llm-unknown')
|
|
225
|
+
expect(() => service.getModel('no-such-role')).toThrow()
|
|
226
|
+
})
|
|
227
|
+
})
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"extends": [
|
|
3
|
+
"@owlmeans/dep-config/tsconfig.base.json",
|
|
4
|
+
"@owlmeans/dep-config/tsconfig.node.json"
|
|
5
|
+
],
|
|
6
|
+
"compilerOptions": {
|
|
7
|
+
"rootDir": "./src/",
|
|
8
|
+
"outDir": "./build/"
|
|
9
|
+
},
|
|
10
|
+
"include": [
|
|
11
|
+
"src/**/*"
|
|
12
|
+
],
|
|
13
|
+
"exclude": [
|
|
14
|
+
"./dist/**/*",
|
|
15
|
+
"./build/**/*",
|
|
16
|
+
"./tests/**/*",
|
|
17
|
+
"./*.ts"
|
|
18
|
+
]
|
|
19
|
+
}
|