dna-sdk 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +58 -0
- package/dist/adapters/embedding/onnx.d.ts +32 -0
- package/dist/adapters/embedding/onnx.js +51 -0
- package/dist/adapters/filesystem/cache.d.ts +16 -0
- package/dist/adapters/filesystem/cache.js +113 -0
- package/dist/adapters/filesystem/index.d.ts +2 -0
- package/dist/adapters/filesystem/index.js +2 -0
- package/dist/adapters/filesystem/source.d.ts +82 -0
- package/dist/adapters/filesystem/source.js +357 -0
- package/dist/adapters/postgres/index.d.ts +2 -0
- package/dist/adapters/postgres/index.js +2 -0
- package/dist/adapters/postgres/migrations.d.ts +14 -0
- package/dist/adapters/postgres/migrations.js +88 -0
- package/dist/adapters/postgres/source.d.ts +172 -0
- package/dist/adapters/postgres/source.js +569 -0
- package/dist/adapters/resolvers/github.d.ts +12 -0
- package/dist/adapters/resolvers/github.js +47 -0
- package/dist/adapters/resolvers/http.d.ts +22 -0
- package/dist/adapters/resolvers/http.js +145 -0
- package/dist/adapters/resolvers/index.d.ts +3 -0
- package/dist/adapters/resolvers/index.js +3 -0
- package/dist/adapters/resolvers/local.d.ts +24 -0
- package/dist/adapters/resolvers/local.js +132 -0
- package/dist/adapters/search/driver.d.ts +45 -0
- package/dist/adapters/search/driver.js +138 -0
- package/dist/adapters/search/migrations.d.ts +26 -0
- package/dist/adapters/search/migrations.js +58 -0
- package/dist/adapters/search/rrf.d.ts +23 -0
- package/dist/adapters/search/rrf.js +42 -0
- package/dist/adapters/search/sqlite-vec.d.ts +66 -0
- package/dist/adapters/search/sqlite-vec.js +294 -0
- package/dist/bootstrap.d.ts +45 -0
- package/dist/bootstrap.js +134 -0
- package/dist/extensions/agentskills/DOCS.md +18 -0
- package/dist/extensions/agentskills.d.ts +28 -0
- package/dist/extensions/agentskills.js +252 -0
- package/dist/extensions/agentsmd/DOCS.md +18 -0
- package/dist/extensions/agentsmd.d.ts +22 -0
- package/dist/extensions/agentsmd.js +170 -0
- package/dist/extensions/audit/kinds/audit-log.kind.yaml +148 -0
- package/dist/extensions/audit.d.ts +25 -0
- package/dist/extensions/audit.js +62 -0
- package/dist/extensions/automation/kinds/automation.kind.yaml +296 -0
- package/dist/extensions/automation/query.d.ts +49 -0
- package/dist/extensions/automation/query.js +77 -0
- package/dist/extensions/automation/write-guards.d.ts +59 -0
- package/dist/extensions/automation/write-guards.js +153 -0
- package/dist/extensions/automation.d.ts +41 -0
- package/dist/extensions/automation.js +54 -0
- package/dist/extensions/collab.d.ts +16 -0
- package/dist/extensions/collab.js +79 -0
- package/dist/extensions/doc/kinds/doc.kind.yaml +118 -0
- package/dist/extensions/doc.d.ts +25 -0
- package/dist/extensions/doc.js +10 -0
- package/dist/extensions/eval/kinds/eval-baseline.kind.yaml +65 -0
- package/dist/extensions/eval/kinds/eval-case.kind.yaml +140 -0
- package/dist/extensions/eval/kinds/eval-run.kind.yaml +134 -0
- package/dist/extensions/eval/kinds/eval-suite.kind.yaml +87 -0
- package/dist/extensions/eval.d.ts +24 -0
- package/dist/extensions/eval.js +31 -0
- package/dist/extensions/evidence/kinds/evidence.kind.yaml +92 -0
- package/dist/extensions/evidence.d.ts +17 -0
- package/dist/extensions/evidence.js +94 -0
- package/dist/extensions/federation.d.ts +22 -0
- package/dist/extensions/federation.js +173 -0
- package/dist/extensions/guardrails/DOCS.md +20 -0
- package/dist/extensions/guardrails.d.ts +31 -0
- package/dist/extensions/guardrails.js +228 -0
- package/dist/extensions/helix/DOCS-Actor.md +20 -0
- package/dist/extensions/helix/DOCS-Agent.md +20 -0
- package/dist/extensions/helix/DOCS-UseCase.md +20 -0
- package/dist/extensions/helix/layers.d.ts +12 -0
- package/dist/extensions/helix/layers.js +18 -0
- package/dist/extensions/helix/write-guards.d.ts +70 -0
- package/dist/extensions/helix/write-guards.js +172 -0
- package/dist/extensions/helix.d.ts +29 -0
- package/dist/extensions/helix.js +963 -0
- package/dist/extensions/helix_extras.d.ts +124 -0
- package/dist/extensions/helix_extras.js +328 -0
- package/dist/extensions/hooks.d.ts +31 -0
- package/dist/extensions/hooks.js +247 -0
- package/dist/extensions/kinddef/DOCS.md +24 -0
- package/dist/extensions/kinddef.d.ts +40 -0
- package/dist/extensions/kinddef.js +171 -0
- package/dist/extensions/lesson.d.ts +6 -0
- package/dist/extensions/lesson.js +194 -0
- package/dist/extensions/modelreg/kinds/model-profile.kind.yaml +155 -0
- package/dist/extensions/modelreg.d.ts +30 -0
- package/dist/extensions/modelreg.js +38 -0
- package/dist/extensions/recognizer.d.ts +34 -0
- package/dist/extensions/recognizer.js +272 -0
- package/dist/extensions/research.d.ts +32 -0
- package/dist/extensions/research.js +292 -0
- package/dist/extensions/safety.d.ts +33 -0
- package/dist/extensions/safety.js +230 -0
- package/dist/extensions/sdlc/kinds/adr.kind.yaml +136 -0
- package/dist/extensions/sdlc/kinds/archive-proposal.kind.yaml +107 -0
- package/dist/extensions/sdlc/kinds/changelog.kind.yaml +108 -0
- package/dist/extensions/sdlc/kinds/cognitive-policy.kind.yaml +470 -0
- package/dist/extensions/sdlc/kinds/forecast.kind.yaml +125 -0
- package/dist/extensions/sdlc/kinds/insight.kind.yaml +87 -0
- package/dist/extensions/sdlc/kinds/kaizen.kind.yaml +106 -0
- package/dist/extensions/sdlc/kinds/lesson-learned.kind.yaml +270 -0
- package/dist/extensions/sdlc/kinds/narrative.kind.yaml +189 -0
- package/dist/extensions/sdlc/kinds/pattern-insight.kind.yaml +204 -0
- package/dist/extensions/sdlc/kinds/postmortem.kind.yaml +168 -0
- package/dist/extensions/sdlc/kinds/pre-mortem.kind.yaml +145 -0
- package/dist/extensions/sdlc/kinds/prompt-template.kind.yaml +109 -0
- package/dist/extensions/sdlc/kinds/retrospective.kind.yaml +186 -0
- package/dist/extensions/sdlc/kinds/risk-register.kind.yaml +178 -0
- package/dist/extensions/sdlc/kinds/saved-view.kind.yaml +127 -0
- package/dist/extensions/sdlc/kinds/status-report.kind.yaml +129 -0
- package/dist/extensions/sdlc/kinds/synthesis-run.kind.yaml +279 -0
- package/dist/extensions/sdlc/kinds/synthesizer-state.kind.yaml +196 -0
- package/dist/extensions/sdlc/kinds/workflow-event.kind.yaml +195 -0
- package/dist/extensions/sdlc.d.ts +32 -0
- package/dist/extensions/sdlc.js +1318 -0
- package/dist/extensions/soulspec/DOCS.md +19 -0
- package/dist/extensions/soulspec.d.ts +22 -0
- package/dist/extensions/soulspec.js +287 -0
- package/dist/extensions/tenant.d.ts +6 -0
- package/dist/extensions/tenant.js +291 -0
- package/dist/extensions/testkit.d.ts +24 -0
- package/dist/extensions/testkit.js +211 -0
- package/dist/index.d.ts +80 -0
- package/dist/index.js +102 -0
- package/dist/kernel/_text.d.ts +28 -0
- package/dist/kernel/_text.js +42 -0
- package/dist/kernel/bundle-handle.d.ts +83 -0
- package/dist/kernel/bundle-handle.js +184 -0
- package/dist/kernel/capabilities.d.ts +157 -0
- package/dist/kernel/capabilities.js +109 -0
- package/dist/kernel/collaborator-ports.d.ts +91 -0
- package/dist/kernel/collaborator-ports.js +1 -0
- package/dist/kernel/composition-resolver.d.ts +215 -0
- package/dist/kernel/composition-resolver.js +558 -0
- package/dist/kernel/composition.d.ts +10 -0
- package/dist/kernel/composition.js +1 -0
- package/dist/kernel/descriptor-loader.d.ts +13 -0
- package/dist/kernel/descriptor-loader.js +48 -0
- package/dist/kernel/document.d.ts +43 -0
- package/dist/kernel/document.js +71 -0
- package/dist/kernel/embedding.d.ts +28 -0
- package/dist/kernel/embedding.js +78 -0
- package/dist/kernel/errors.d.ts +62 -0
- package/dist/kernel/errors.js +82 -0
- package/dist/kernel/events.d.ts +6 -0
- package/dist/kernel/events.js +21 -0
- package/dist/kernel/evidence-capture.d.ts +69 -0
- package/dist/kernel/evidence-capture.js +138 -0
- package/dist/kernel/fs.d.ts +20 -0
- package/dist/kernel/fs.js +128 -0
- package/dist/kernel/generic-rw.d.ts +33 -0
- package/dist/kernel/generic-rw.js +235 -0
- package/dist/kernel/hooks.d.ts +172 -0
- package/dist/kernel/hooks.js +256 -0
- package/dist/kernel/index.d.ts +624 -0
- package/dist/kernel/index.js +1638 -0
- package/dist/kernel/instance.d.ts +211 -0
- package/dist/kernel/instance.js +487 -0
- package/dist/kernel/kind-registry.d.ts +183 -0
- package/dist/kernel/kind-registry.js +710 -0
- package/dist/kernel/kind_base.d.ts +106 -0
- package/dist/kernel/kind_base.js +244 -0
- package/dist/kernel/layer-resolver.d.ts +48 -0
- package/dist/kernel/layer-resolver.js +284 -0
- package/dist/kernel/lock-manager.d.ts +21 -0
- package/dist/kernel/lock-manager.js +43 -0
- package/dist/kernel/lock.d.ts +38 -0
- package/dist/kernel/lock.js +115 -0
- package/dist/kernel/meta.d.ts +135 -0
- package/dist/kernel/meta.js +817 -0
- package/dist/kernel/models.d.ts +3089 -0
- package/dist/kernel/models.js +764 -0
- package/dist/kernel/navigator.d.ts +36 -0
- package/dist/kernel/navigator.js +132 -0
- package/dist/kernel/port-surface.d.ts +33 -0
- package/dist/kernel/port-surface.js +180 -0
- package/dist/kernel/preview.d.ts +60 -0
- package/dist/kernel/preview.js +54 -0
- package/dist/kernel/prompt-budget.d.ts +39 -0
- package/dist/kernel/prompt-budget.js +43 -0
- package/dist/kernel/prompt-builder.d.ts +25 -0
- package/dist/kernel/prompt-builder.js +237 -0
- package/dist/kernel/protocols.d.ts +751 -0
- package/dist/kernel/protocols.js +493 -0
- package/dist/kernel/reports.d.ts +26 -0
- package/dist/kernel/reports.js +215 -0
- package/dist/kernel/resolver.d.ts +146 -0
- package/dist/kernel/resolver.js +232 -0
- package/dist/kernel/resource.d.ts +57 -0
- package/dist/kernel/resource.js +97 -0
- package/dist/kernel/runtime.d.ts +16 -0
- package/dist/kernel/runtime.js +18 -0
- package/dist/kernel/safety-scanner.d.ts +38 -0
- package/dist/kernel/safety-scanner.js +228 -0
- package/dist/kernel/serialize-to-files.d.ts +29 -0
- package/dist/kernel/serialize-to-files.js +23 -0
- package/dist/kernel/spec-access.d.ts +23 -0
- package/dist/kernel/spec-access.js +40 -0
- package/dist/kernel/studio_ui.d.ts +88 -0
- package/dist/kernel/studio_ui.js +135 -0
- package/dist/kernel/templates.d.ts +77 -0
- package/dist/kernel/templates.js +116 -0
- package/dist/kernel/tool-registry.d.ts +52 -0
- package/dist/kernel/tool-registry.js +89 -0
- package/dist/kernel/write-pipeline.d.ts +65 -0
- package/dist/kernel/write-pipeline.js +271 -0
- package/dist/kernel/writer-helpers.d.ts +24 -0
- package/dist/kernel/writer-helpers.js +42 -0
- package/dist/memory/decay.d.ts +31 -0
- package/dist/memory/decay.js +97 -0
- package/dist/memory/ecphory.d.ts +25 -0
- package/dist/memory/ecphory.js +178 -0
- package/dist/memory/encodingContext.d.ts +21 -0
- package/dist/memory/encodingContext.js +62 -0
- package/dist/memory/index.d.ts +23 -0
- package/dist/memory/index.js +23 -0
- package/dist/memory/memoryType.d.ts +7 -0
- package/dist/memory/memoryType.js +24 -0
- package/dist/memory/policy.d.ts +35 -0
- package/dist/memory/policy.js +35 -0
- package/dist/memory/retrieval.d.ts +21 -0
- package/dist/memory/retrieval.js +145 -0
- package/dist/testing/index.d.ts +8 -0
- package/dist/testing/index.js +8 -0
- package/dist/testing/recordSearchConformance.d.ts +43 -0
- package/dist/testing/recordSearchConformance.js +147 -0
- package/dist/viz/ascii.d.ts +7 -0
- package/dist/viz/ascii.js +60 -0
- package/dist/viz/health.d.ts +8 -0
- package/dist/viz/health.js +161 -0
- package/dist/viz/index.d.ts +10 -0
- package/dist/viz/index.js +10 -0
- package/dist/viz/matrix.d.ts +8 -0
- package/dist/viz/matrix.js +84 -0
- package/dist/viz/mermaid.d.ts +38 -0
- package/dist/viz/mermaid.js +706 -0
- package/package.json +82 -0
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
# ModelProfile — per-LLM-model capability/limit registry (record plane).
|
|
2
|
+
# One doc per model: hard limits (instruction_token_cap, context_window,
|
|
3
|
+
# tools_cap, max_output_tokens) + modalities + cost, as first-class GLOBAL
|
|
4
|
+
# data so limits are project data, not implicit knowledge. Ported from the
|
|
5
|
+
# internal SDK's model registry, motivated by a real outage: a 17269-token
|
|
6
|
+
# voice persona silently exceeded the realtime model's 16384-token
|
|
7
|
+
# session-instructions cap because the cap lived in nobody's code.
|
|
8
|
+
#
|
|
9
|
+
# CONTRACT — never hardcode token caps: the prompt-budget write guard
|
|
10
|
+
# (dna/extensions/helix/write_guards.py :: prompt_budget_guard and its TS
|
|
11
|
+
# twin) reads instruction_token_cap from THIS registry via
|
|
12
|
+
# kernel.model_profile(id_or_alias); a cap literal in code is a bug.
|
|
13
|
+
#
|
|
14
|
+
# Profiles live in the `_lib` scope (`model-profiles/<model_id>.yaml`) —
|
|
15
|
+
# ModelProfile is GLOBAL (base only, no per-tenant override) and NOT
|
|
16
|
+
# inheritable; kernel.model_profile() queries `_lib` directly regardless
|
|
17
|
+
# of the caller's scope.
|
|
18
|
+
#
|
|
19
|
+
# PARITY-CRITICAL package data: the byte-identical mirror lives at
|
|
20
|
+
# packages/sdk-{py,ts}/{dna/extensions,src/extensions}/modelreg/kinds/
|
|
21
|
+
# model-profile.kind.yaml (tests/test_descriptor_hash_parity.py enforces).
|
|
22
|
+
apiVersion: github.com/ruinosus/dna/core/v1
|
|
23
|
+
kind: KindDefinition
|
|
24
|
+
metadata:
|
|
25
|
+
name: model-profile
|
|
26
|
+
spec:
|
|
27
|
+
target_api_version: github.com/ruinosus/dna/modelreg/v1
|
|
28
|
+
target_kind: ModelProfile
|
|
29
|
+
alias: modelreg-model-profile
|
|
30
|
+
origin: github.com/ruinosus/dna/modelreg
|
|
31
|
+
tenant_scope: global
|
|
32
|
+
plane: record
|
|
33
|
+
prompt_target: false
|
|
34
|
+
flatten_in_context: false
|
|
35
|
+
prompt_target_priority: 0
|
|
36
|
+
storage:
|
|
37
|
+
type: yaml
|
|
38
|
+
container: model-profiles
|
|
39
|
+
schema:
|
|
40
|
+
type: object
|
|
41
|
+
required:
|
|
42
|
+
- model_id
|
|
43
|
+
- provider
|
|
44
|
+
properties:
|
|
45
|
+
model_id:
|
|
46
|
+
type: string
|
|
47
|
+
description: Canonical model identifier, e.g. 'gpt-realtime-2'. The doc
|
|
48
|
+
name SHOULD equal the model_id; kernel.model_profile() matches on this
|
|
49
|
+
field first.
|
|
50
|
+
provider:
|
|
51
|
+
type: string
|
|
52
|
+
description: Who serves the model — 'openai', 'anthropic', 'azure', a
|
|
53
|
+
proxy alias, etc.
|
|
54
|
+
family:
|
|
55
|
+
type:
|
|
56
|
+
- string
|
|
57
|
+
- 'null'
|
|
58
|
+
description: Model family/lineage for grouping, e.g. 'gpt-realtime'.
|
|
59
|
+
realtime:
|
|
60
|
+
type: boolean
|
|
61
|
+
default: false
|
|
62
|
+
description: 'True for realtime voice models. STRICT marker: the
|
|
63
|
+
prompt-budget guard VETOES an over-cap write against a realtime
|
|
64
|
+
profile (voice sessions silently degrade past the cap); chat profiles
|
|
65
|
+
only warn.'
|
|
66
|
+
context_window:
|
|
67
|
+
type: integer
|
|
68
|
+
description: Total context window in tokens.
|
|
69
|
+
instruction_token_cap:
|
|
70
|
+
type:
|
|
71
|
+
- integer
|
|
72
|
+
- 'null'
|
|
73
|
+
description: Hard cap for the system-instruction/persona in tokens.
|
|
74
|
+
Null = no cap known (the guard fails open). THE value the
|
|
75
|
+
prompt-budget guard enforces — never hardcode it in code.
|
|
76
|
+
max_output_tokens:
|
|
77
|
+
type:
|
|
78
|
+
- integer
|
|
79
|
+
- 'null'
|
|
80
|
+
description: Max completion/output tokens per response.
|
|
81
|
+
tools_cap:
|
|
82
|
+
type:
|
|
83
|
+
- integer
|
|
84
|
+
- 'null'
|
|
85
|
+
description: Max number of tools the model accepts per session.
|
|
86
|
+
modalities:
|
|
87
|
+
type: array
|
|
88
|
+
items:
|
|
89
|
+
type: string
|
|
90
|
+
description: Supported modalities, e.g. [text], [text, audio],
|
|
91
|
+
[text, image].
|
|
92
|
+
cost_per_1m_input_usd:
|
|
93
|
+
type:
|
|
94
|
+
- number
|
|
95
|
+
- 'null'
|
|
96
|
+
description: USD per 1M input tokens (informational).
|
|
97
|
+
cost_per_1m_output_usd:
|
|
98
|
+
type:
|
|
99
|
+
- number
|
|
100
|
+
- 'null'
|
|
101
|
+
description: USD per 1M output tokens (informational).
|
|
102
|
+
aliases:
|
|
103
|
+
type: array
|
|
104
|
+
items:
|
|
105
|
+
type: string
|
|
106
|
+
description: Alternate ids that resolve to this profile (deployment
|
|
107
|
+
names, dated snapshots). kernel.model_profile() matches these on
|
|
108
|
+
pass 2.
|
|
109
|
+
deprecated:
|
|
110
|
+
type: boolean
|
|
111
|
+
default: false
|
|
112
|
+
description: True when the model is scheduled for removal.
|
|
113
|
+
deprecated_message:
|
|
114
|
+
type:
|
|
115
|
+
- string
|
|
116
|
+
- 'null'
|
|
117
|
+
description: Human guidance shown when a deprecated model is used.
|
|
118
|
+
notes:
|
|
119
|
+
type:
|
|
120
|
+
- string
|
|
121
|
+
- 'null'
|
|
122
|
+
description: Free-form operator notes.
|
|
123
|
+
describe: '{provider}/{model_id}'
|
|
124
|
+
summary:
|
|
125
|
+
model_id: ''
|
|
126
|
+
provider: ''
|
|
127
|
+
family: null
|
|
128
|
+
realtime: false
|
|
129
|
+
context_window: null
|
|
130
|
+
instruction_token_cap: null
|
|
131
|
+
deprecated: false
|
|
132
|
+
ui:
|
|
133
|
+
mode: govern
|
|
134
|
+
label:
|
|
135
|
+
en: Model Profiles
|
|
136
|
+
pt-BR: Perfis de Modelo
|
|
137
|
+
icon: 🧬
|
|
138
|
+
description:
|
|
139
|
+
en: Per-LLM-model limits/capabilities.
|
|
140
|
+
pt-BR: Limites/capacidades por modelo LLM.
|
|
141
|
+
routes:
|
|
142
|
+
list: docs/ModelProfile
|
|
143
|
+
detail: docs/ModelProfile/:name
|
|
144
|
+
permissions:
|
|
145
|
+
list: any
|
|
146
|
+
detail: any
|
|
147
|
+
in_sidebar: true
|
|
148
|
+
display_order: 52
|
|
149
|
+
ascii_icon: 🧬
|
|
150
|
+
display_label: Model Profiles
|
|
151
|
+
docs: A ModelProfile records one LLM model's hard limits and capabilities
|
|
152
|
+
(instruction_token_cap, context_window, tools_cap, modalities, cost). It is
|
|
153
|
+
the single source of truth the prompt-budget write guard reads — never
|
|
154
|
+
hardcode token caps in code; read them from the ModelProfile registry via
|
|
155
|
+
kernel.model_profile().
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ModelRegExtension — per-model capability/limit registry.
|
|
3
|
+
*
|
|
4
|
+
* 1:1 parity with Python `dna.extensions.modelreg`.
|
|
5
|
+
*
|
|
6
|
+
* Registers 1 Kind, from a descriptor (F3 — record Kinds are data, not
|
|
7
|
+
* classes):
|
|
8
|
+
*
|
|
9
|
+
* - ModelProfile (`modelreg-model-profile`) — hard limits
|
|
10
|
+
* (`instruction_token_cap`, `context_window`, `tools_cap`) +
|
|
11
|
+
* modalities + cost of one LLM model, as a first-class GLOBAL Kind so
|
|
12
|
+
* limits are project data, not implicit knowledge. Ported from the
|
|
13
|
+
* internal SDK's model registry, motivated by a real outage: a
|
|
14
|
+
* 17269-token voice persona silently exceeded the realtime model's
|
|
15
|
+
* 16384-token session-instructions cap because the cap lived in
|
|
16
|
+
* nobody's code.
|
|
17
|
+
*
|
|
18
|
+
* CONTRACT — never hardcode token caps. The single source of truth for a
|
|
19
|
+
* model's limits is its ModelProfile doc (`_lib` scope,
|
|
20
|
+
* `model-profiles/<model_id>.yaml`), resolved via
|
|
21
|
+
* `kernel.modelProfile(idOrAlias)`. The prompt-budget write guard
|
|
22
|
+
* (`src/extensions/helix/write-guards.ts` + Python twin) reads the cap
|
|
23
|
+
* from there — a token-cap literal in code is a bug.
|
|
24
|
+
*/
|
|
25
|
+
import type { ExtensionHost, Extension } from "../kernel/protocols.js";
|
|
26
|
+
export declare class ModelRegExtension implements Extension {
|
|
27
|
+
name: string;
|
|
28
|
+
version: string;
|
|
29
|
+
register(kernel: ExtensionHost): void;
|
|
30
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ModelRegExtension — per-model capability/limit registry.
|
|
3
|
+
*
|
|
4
|
+
* 1:1 parity with Python `dna.extensions.modelreg`.
|
|
5
|
+
*
|
|
6
|
+
* Registers 1 Kind, from a descriptor (F3 — record Kinds are data, not
|
|
7
|
+
* classes):
|
|
8
|
+
*
|
|
9
|
+
* - ModelProfile (`modelreg-model-profile`) — hard limits
|
|
10
|
+
* (`instruction_token_cap`, `context_window`, `tools_cap`) +
|
|
11
|
+
* modalities + cost of one LLM model, as a first-class GLOBAL Kind so
|
|
12
|
+
* limits are project data, not implicit knowledge. Ported from the
|
|
13
|
+
* internal SDK's model registry, motivated by a real outage: a
|
|
14
|
+
* 17269-token voice persona silently exceeded the realtime model's
|
|
15
|
+
* 16384-token session-instructions cap because the cap lived in
|
|
16
|
+
* nobody's code.
|
|
17
|
+
*
|
|
18
|
+
* CONTRACT — never hardcode token caps. The single source of truth for a
|
|
19
|
+
* model's limits is its ModelProfile doc (`_lib` scope,
|
|
20
|
+
* `model-profiles/<model_id>.yaml`), resolved via
|
|
21
|
+
* `kernel.modelProfile(idOrAlias)`. The prompt-budget write guard
|
|
22
|
+
* (`src/extensions/helix/write-guards.ts` + Python twin) reads the cap
|
|
23
|
+
* from there — a token-cap literal in code is a bug.
|
|
24
|
+
*/
|
|
25
|
+
import { loadDescriptors } from "../kernel/descriptor-loader.js";
|
|
26
|
+
export class ModelRegExtension {
|
|
27
|
+
name = "modelreg";
|
|
28
|
+
version = "1.0.0";
|
|
29
|
+
register(kernel) {
|
|
30
|
+
// F3: ModelProfile ships as kinds/model-profile.kind.yaml package data
|
|
31
|
+
// (byte-identical Py↔TS mirror), registered through the SAME funnel as
|
|
32
|
+
// per-scope KindDefinitions (plane lint + digest idempotency + builtin
|
|
33
|
+
// conflict marker).
|
|
34
|
+
for (const raw of loadDescriptors(import.meta.url, "modelreg/kinds")) {
|
|
35
|
+
kernel.kindFromDescriptor(raw);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RecognizerExtension — Recognizer kind (Presidio ad-hoc recognizer).
|
|
3
|
+
*
|
|
4
|
+
* Declares PII detection patterns as manifest documents. Recognizers are
|
|
5
|
+
* referenced by SafetyPolicy documents via dep_filters and exported to
|
|
6
|
+
* LiteLLM/Presidio at runtime.
|
|
7
|
+
*
|
|
8
|
+
* 1:1 parity with Python dna.extensions.recognizer.
|
|
9
|
+
*/
|
|
10
|
+
import type { BundleHandle } from "../kernel/bundle-handle.js";
|
|
11
|
+
import type { FSLike } from "../kernel/fs.js";
|
|
12
|
+
import type { ExtensionHost, Extension, ReaderPort, SerializedFile, WriterPort } from "../kernel/protocols.js";
|
|
13
|
+
export declare class RecognizerReader implements ReaderPort {
|
|
14
|
+
private fs;
|
|
15
|
+
readonly _marker = "RECOGNIZER.md";
|
|
16
|
+
constructor(fs?: FSLike);
|
|
17
|
+
detect(bundle: BundleHandle): boolean;
|
|
18
|
+
read(bundle: BundleHandle): Record<string, unknown>;
|
|
19
|
+
}
|
|
20
|
+
export declare class RecognizerWriter implements WriterPort {
|
|
21
|
+
private fs;
|
|
22
|
+
readonly _kind = "Recognizer";
|
|
23
|
+
constructor(fs?: FSLike);
|
|
24
|
+
canWrite(raw: Record<string, unknown>): boolean;
|
|
25
|
+
write(bundle: BundleHandle, raw: Record<string, unknown>): void;
|
|
26
|
+
serialize(raw: Record<string, unknown>): SerializedFile[];
|
|
27
|
+
}
|
|
28
|
+
export declare class RecognizerExtension implements Extension {
|
|
29
|
+
private fs;
|
|
30
|
+
readonly name = "recognizer";
|
|
31
|
+
readonly version = "1.0.0";
|
|
32
|
+
constructor(fs?: FSLike);
|
|
33
|
+
register(kernel: ExtensionHost): void;
|
|
34
|
+
}
|
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RecognizerExtension — Recognizer kind (Presidio ad-hoc recognizer).
|
|
3
|
+
*
|
|
4
|
+
* Declares PII detection patterns as manifest documents. Recognizers are
|
|
5
|
+
* referenced by SafetyPolicy documents via dep_filters and exported to
|
|
6
|
+
* LiteLLM/Presidio at runtime.
|
|
7
|
+
*
|
|
8
|
+
* 1:1 parity with Python dna.extensions.recognizer.
|
|
9
|
+
*/
|
|
10
|
+
import yaml from "js-yaml";
|
|
11
|
+
import { nodeFS } from "../kernel/fs.js";
|
|
12
|
+
import { KindBase } from "../kernel/kind_base.js";
|
|
13
|
+
import { RecognizerSchema, RecognizerSpecSchema, zodSpecToJsonSchema } from "../kernel/models.js";
|
|
14
|
+
import { SD } from "../kernel/protocols.js";
|
|
15
|
+
// ---------------------------------------------------------------------------
|
|
16
|
+
// RecognizerKind
|
|
17
|
+
// ---------------------------------------------------------------------------
|
|
18
|
+
class RecognizerKind extends KindBase {
|
|
19
|
+
apiVersion = "presidio/v1";
|
|
20
|
+
kind = "Recognizer";
|
|
21
|
+
alias = "presidio-recognizer";
|
|
22
|
+
isSchemaAffecting = true;
|
|
23
|
+
origin = "microsoft.github.io/presidio";
|
|
24
|
+
isPromptTarget = false;
|
|
25
|
+
promptTargetPriority = 0;
|
|
26
|
+
flattenInContext = false;
|
|
27
|
+
descriptionFallbackField = "entity_type";
|
|
28
|
+
storage = SD.bundle("recognizers", "RECOGNIZER.md", "text", "patterns");
|
|
29
|
+
graphStyle = { fill: "#6366F1", stroke: "#4F46E5", textColor: "#fff" };
|
|
30
|
+
asciiIcon = "\uD83D\uDD0D";
|
|
31
|
+
displayLabel = "Recognizers";
|
|
32
|
+
_sourceUrl = import.meta.url;
|
|
33
|
+
docs = "A Recognizer is a Presidio ad-hoc recognizer that detects PII entities " +
|
|
34
|
+
"using regex patterns or deny lists. Recognizers are referenced by " +
|
|
35
|
+
"SafetyPolicy documents and exported to LiteLLM/Presidio at runtime.";
|
|
36
|
+
uiSchema = {
|
|
37
|
+
entity_type: {
|
|
38
|
+
widget: "input",
|
|
39
|
+
label: "Entity Type",
|
|
40
|
+
help: "Presidio entity name, e.g. BR_CPF, BR_CNPJ",
|
|
41
|
+
order: 1,
|
|
42
|
+
},
|
|
43
|
+
language: {
|
|
44
|
+
widget: "select",
|
|
45
|
+
options: ["en", "pt", "es", "de", "fr"],
|
|
46
|
+
label: "Language",
|
|
47
|
+
order: 2,
|
|
48
|
+
},
|
|
49
|
+
patterns: {
|
|
50
|
+
widget: "code",
|
|
51
|
+
language: "yaml",
|
|
52
|
+
label: "Patterns",
|
|
53
|
+
help: "List of {name, regex, score} objects",
|
|
54
|
+
height: 200,
|
|
55
|
+
order: 3,
|
|
56
|
+
},
|
|
57
|
+
deny_list: {
|
|
58
|
+
widget: "tags",
|
|
59
|
+
label: "Deny List",
|
|
60
|
+
help: "Words that always match this entity",
|
|
61
|
+
order: 4,
|
|
62
|
+
},
|
|
63
|
+
context: {
|
|
64
|
+
widget: "tags",
|
|
65
|
+
label: "Context Words",
|
|
66
|
+
help: "Words near the entity that boost confidence",
|
|
67
|
+
order: 5,
|
|
68
|
+
},
|
|
69
|
+
};
|
|
70
|
+
schema() { return zodSpecToJsonSchema(RecognizerSpecSchema); }
|
|
71
|
+
parse(raw) {
|
|
72
|
+
// patterns comes as raw text (body_as=text). Parse as YAML to get array of pattern objects.
|
|
73
|
+
const spec = (raw.spec ?? {});
|
|
74
|
+
if (typeof spec.patterns === "string" && spec.patterns.trim()) {
|
|
75
|
+
try {
|
|
76
|
+
const parsed = yaml.load(spec.patterns);
|
|
77
|
+
if (Array.isArray(parsed)) {
|
|
78
|
+
spec.patterns = parsed;
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
spec.patterns = [];
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
catch {
|
|
85
|
+
spec.patterns = [];
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return RecognizerSchema.parse(raw);
|
|
89
|
+
}
|
|
90
|
+
describe(doc) {
|
|
91
|
+
const spec = (doc.spec ?? {});
|
|
92
|
+
return `Recognizer: ${doc.name} (entity=${spec.entity_type})`;
|
|
93
|
+
}
|
|
94
|
+
summary(doc) {
|
|
95
|
+
const spec = (doc.spec ?? {});
|
|
96
|
+
return {
|
|
97
|
+
entity_type: typeof spec.entity_type === "string" ? spec.entity_type : "",
|
|
98
|
+
language: typeof spec.language === "string" ? spec.language : "en",
|
|
99
|
+
patterns: Array.isArray(spec.patterns) ? spec.patterns.length : 0,
|
|
100
|
+
deny_list: Array.isArray(spec.deny_list) ? spec.deny_list.length : 0,
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
preview(doc) {
|
|
104
|
+
const spec = (doc.spec ?? {});
|
|
105
|
+
const blocks = [];
|
|
106
|
+
const meta = [];
|
|
107
|
+
if (typeof spec.entity_type === "string")
|
|
108
|
+
meta.push({ label: "Entity Type", value: spec.entity_type });
|
|
109
|
+
if (typeof spec.language === "string")
|
|
110
|
+
meta.push({ label: "Language", value: spec.language });
|
|
111
|
+
if (meta.length > 0) {
|
|
112
|
+
blocks.push({ kind: "fields", title: "Recognizer", fields: meta });
|
|
113
|
+
}
|
|
114
|
+
const patterns = spec.patterns;
|
|
115
|
+
if (Array.isArray(patterns) && patterns.length > 0) {
|
|
116
|
+
blocks.push({
|
|
117
|
+
kind: "code",
|
|
118
|
+
title: "Patterns",
|
|
119
|
+
body: yaml.dump(patterns, { flowLevel: 3 }).trim(),
|
|
120
|
+
language: "yaml",
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
const denyList = spec.deny_list;
|
|
124
|
+
if (Array.isArray(denyList) && denyList.length > 0) {
|
|
125
|
+
blocks.push({
|
|
126
|
+
kind: "code",
|
|
127
|
+
title: "Deny List",
|
|
128
|
+
body: denyList.join(", "),
|
|
129
|
+
language: "text",
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
const context = spec.context;
|
|
133
|
+
if (Array.isArray(context) && context.length > 0) {
|
|
134
|
+
blocks.push({
|
|
135
|
+
kind: "code",
|
|
136
|
+
title: "Context Words",
|
|
137
|
+
body: context.join(", "),
|
|
138
|
+
language: "text",
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
if (blocks.length === 0) {
|
|
142
|
+
return [{ kind: "empty", title: "Recognizer (empty)" }];
|
|
143
|
+
}
|
|
144
|
+
return blocks;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
// ---------------------------------------------------------------------------
|
|
148
|
+
// RecognizerReader
|
|
149
|
+
// ---------------------------------------------------------------------------
|
|
150
|
+
function parseFrontmatter(text) {
|
|
151
|
+
const match = text.match(/^---\n([\s\S]*?)---\n?/);
|
|
152
|
+
if (!match)
|
|
153
|
+
return [{}, text];
|
|
154
|
+
let fm = {};
|
|
155
|
+
try {
|
|
156
|
+
const parsed = yaml.load(match[1]);
|
|
157
|
+
if (typeof parsed === "object" && parsed !== null) {
|
|
158
|
+
fm = parsed;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
catch { /* ignore */ }
|
|
162
|
+
const body = text.slice(match[0].length);
|
|
163
|
+
return [fm, body];
|
|
164
|
+
}
|
|
165
|
+
export class RecognizerReader {
|
|
166
|
+
fs;
|
|
167
|
+
_marker = "RECOGNIZER.md";
|
|
168
|
+
constructor(fs = nodeFS) {
|
|
169
|
+
this.fs = fs;
|
|
170
|
+
}
|
|
171
|
+
detect(bundle) {
|
|
172
|
+
const path = bundle.path ?? "";
|
|
173
|
+
return this.fs.exists(`${path}/RECOGNIZER.md`);
|
|
174
|
+
}
|
|
175
|
+
read(bundle) {
|
|
176
|
+
const path = bundle.path ?? "";
|
|
177
|
+
const text = this.fs.readFile(`${path}/RECOGNIZER.md`);
|
|
178
|
+
const [fm, body] = parseFrontmatter(text);
|
|
179
|
+
const name = String(fm.name || "") || path.split("/").pop() || "";
|
|
180
|
+
const description = String(fm.description || "");
|
|
181
|
+
const entity_type = String(fm.entity_type || "");
|
|
182
|
+
const language = String(fm.language || "en");
|
|
183
|
+
// Parse deny_list and context from frontmatter
|
|
184
|
+
const deny_list = Array.isArray(fm.deny_list) ? fm.deny_list.map(String) : [];
|
|
185
|
+
const context = Array.isArray(fm.context) ? fm.context.map(String) : [];
|
|
186
|
+
// Parse body as YAML list of pattern objects
|
|
187
|
+
let patterns = [];
|
|
188
|
+
const trimmedBody = body.trim();
|
|
189
|
+
if (trimmedBody) {
|
|
190
|
+
try {
|
|
191
|
+
const parsed = yaml.load(trimmedBody);
|
|
192
|
+
if (Array.isArray(parsed)) {
|
|
193
|
+
patterns = parsed;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
catch { /* ignore invalid YAML */ }
|
|
197
|
+
}
|
|
198
|
+
return {
|
|
199
|
+
apiVersion: "presidio/v1",
|
|
200
|
+
kind: "Recognizer",
|
|
201
|
+
metadata: { name, description },
|
|
202
|
+
spec: { entity_type, language, patterns, deny_list, context },
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
// ---------------------------------------------------------------------------
|
|
207
|
+
// RecognizerWriter
|
|
208
|
+
// ---------------------------------------------------------------------------
|
|
209
|
+
export class RecognizerWriter {
|
|
210
|
+
fs;
|
|
211
|
+
_kind = "Recognizer";
|
|
212
|
+
constructor(fs = nodeFS) {
|
|
213
|
+
this.fs = fs;
|
|
214
|
+
}
|
|
215
|
+
canWrite(raw) {
|
|
216
|
+
return raw.kind === "Recognizer";
|
|
217
|
+
}
|
|
218
|
+
write(bundle, raw) {
|
|
219
|
+
const path = bundle.path ?? "";
|
|
220
|
+
this.fs.mkdir(path);
|
|
221
|
+
for (const f of this.serialize(raw)) {
|
|
222
|
+
this.fs.writeFile(`${path}/${f.relativePath}`, f.content ?? "");
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
serialize(raw) {
|
|
226
|
+
const meta = (raw.metadata ?? {});
|
|
227
|
+
const spec = (raw.spec ?? {});
|
|
228
|
+
const fmParts = [];
|
|
229
|
+
if (meta.name)
|
|
230
|
+
fmParts.push(`name: ${meta.name}`);
|
|
231
|
+
if (meta.description)
|
|
232
|
+
fmParts.push(`description: ${meta.description}`);
|
|
233
|
+
if (spec.entity_type)
|
|
234
|
+
fmParts.push(`entity_type: ${spec.entity_type}`);
|
|
235
|
+
fmParts.push(`language: ${spec.language ?? "en"}`);
|
|
236
|
+
const denyList = spec.deny_list;
|
|
237
|
+
if (denyList && denyList.length > 0) {
|
|
238
|
+
fmParts.push(`deny_list:\n${denyList.map(w => ` - ${w}`).join("\n")}`);
|
|
239
|
+
}
|
|
240
|
+
const context = spec.context;
|
|
241
|
+
if (context && context.length > 0) {
|
|
242
|
+
fmParts.push(`context:\n${context.map(w => ` - ${w}`).join("\n")}`);
|
|
243
|
+
}
|
|
244
|
+
const frontmatter = fmParts.join("\n");
|
|
245
|
+
// Serialize patterns as YAML list
|
|
246
|
+
const patterns = spec.patterns ?? [];
|
|
247
|
+
let body = "";
|
|
248
|
+
if (patterns.length > 0) {
|
|
249
|
+
body = yaml.dump(patterns, { flowLevel: 3 }).trim();
|
|
250
|
+
}
|
|
251
|
+
const content = body
|
|
252
|
+
? `---\n${frontmatter}\n---\n\n${body}\n`
|
|
253
|
+
: `---\n${frontmatter}\n---\n`;
|
|
254
|
+
return [{ relativePath: "RECOGNIZER.md", content }];
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
// ---------------------------------------------------------------------------
|
|
258
|
+
// Extension
|
|
259
|
+
// ---------------------------------------------------------------------------
|
|
260
|
+
export class RecognizerExtension {
|
|
261
|
+
fs;
|
|
262
|
+
name = "recognizer";
|
|
263
|
+
version = "1.0.0";
|
|
264
|
+
constructor(fs = nodeFS) {
|
|
265
|
+
this.fs = fs;
|
|
266
|
+
}
|
|
267
|
+
register(kernel) {
|
|
268
|
+
kernel.kind(new RecognizerKind());
|
|
269
|
+
kernel.reader(new RecognizerReader(this.fs));
|
|
270
|
+
kernel.writer(new RecognizerWriter(this.fs));
|
|
271
|
+
}
|
|
272
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ResearchExtension — curated research syntheses with evidence ratings (TS twin).
|
|
3
|
+
*
|
|
4
|
+
* 1:1 parity with python/dna/extensions/research/__init__.py.
|
|
5
|
+
*
|
|
6
|
+
* Storage layout per doc:
|
|
7
|
+
*
|
|
8
|
+
* .dna/<scope>/research/<name>/
|
|
9
|
+
* RESEARCH.md ← marker (frontmatter = spec)
|
|
10
|
+
*
|
|
11
|
+
* A Research synthesizes N Reference docs with objective, methodology,
|
|
12
|
+
* evidence-rated findings, and priority recommendations — agent-facing
|
|
13
|
+
* knowledge WITH provenance (the declarative counter to LLM-generated
|
|
14
|
+
* repo-wiki prose).
|
|
15
|
+
*
|
|
16
|
+
* Tenancy: PERMISSIVE — no `scope` attribute declared, so the write
|
|
17
|
+
* pipeline treats it as permissive (base writes with or without a
|
|
18
|
+
* tenant). Research is repo-authored knowledge, not per-client data.
|
|
19
|
+
*
|
|
20
|
+
* The Reference companion Kind is provided by the sdlc extension
|
|
21
|
+
* (alias sdlc-reference); it is NOT registered here.
|
|
22
|
+
*/
|
|
23
|
+
import type { ExtensionHost, Extension } from "../kernel/protocols.js";
|
|
24
|
+
export declare const METHODOLOGIES: readonly ["web-search-curated", "literature-review", "interview", "field-study", "experiment", "synthesis", "other"];
|
|
25
|
+
export declare const EVIDENCE_RATINGS: readonly ["evidence-based", "opinion-practice", "anecdotal"];
|
|
26
|
+
export declare const STATUSES: readonly ["brief", "ready", "draft", "published", "superseded", "retracted"];
|
|
27
|
+
export declare const VISIBILITY: readonly ["scope-private", "shared"];
|
|
28
|
+
export declare class ResearchExtension implements Extension {
|
|
29
|
+
name: string;
|
|
30
|
+
version: string;
|
|
31
|
+
register(kernel: ExtensionHost): void;
|
|
32
|
+
}
|