@polymorphism-tech/morph-spec 8.38.0 → 8.40.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 (227) hide show
  1. package/CLAUDE.md +19 -8
  2. package/README.md +2 -2
  3. package/bin/morph-spec.js +60 -43
  4. package/claude-plugin.json +1 -1
  5. package/docs/CHEATSHEET.md +1 -1
  6. package/docs/QUICKSTART.md +1 -1
  7. package/framework/CLAUDE.md +3 -2
  8. package/framework/MORPH.md +1 -1
  9. package/framework/agents.json +36 -25
  10. package/framework/docs/CLI.md +2 -2
  11. package/framework/evals/rubrics/code-quality.md +4 -4
  12. package/framework/evals/rubrics/condensed.md +2 -2
  13. package/framework/mcp/registry.json +33 -2
  14. package/framework/rules/infrastructure-standards.md +0 -1
  15. package/framework/rules/morph-workflow.md +9 -4
  16. package/framework/skills/core/create-umbraco-lp/SKILL.md +1 -1
  17. package/framework/skills/core/migrate-lp-to-umbraco/SKILL.md +1 -1
  18. package/framework/skills/core/morph-apply/SKILL.md +5 -1
  19. package/framework/skills/core/morph-brainstorming/SKILL.md +1 -1
  20. package/framework/skills/core/morph-eval/SKILL.md +1 -1
  21. package/framework/skills/core/morph-hotfix/SKILL.md +1 -1
  22. package/framework/skills/core/morph-implement/SKILL.md +6 -1
  23. package/framework/skills/core/morph-media/SKILL.md +1 -1
  24. package/framework/skills/core/morph-plan/SKILL.md +4 -3
  25. package/framework/skills/core/morph-proposal/SKILL.md +1 -1
  26. package/framework/skills/core/morph-review/SKILL.md +1 -1
  27. package/framework/skills/core/morph-stack-scan/SKILL.md +1 -1
  28. package/framework/skills/core/morph-standards/SKILL.md +1 -1
  29. package/framework/skills/core/morph-uiux/SKILL.md +6 -5
  30. package/framework/standards/STANDARDS.json +3 -3
  31. package/framework/standards/ai-agents/context-providers.md +16 -26
  32. package/framework/standards/ai-agents/durable-workflows-hitl.md +15 -21
  33. package/framework/standards/ai-agents/modalities-image-gen.md +21 -25
  34. package/framework/standards/ai-agents/modalities-speech-to-text.md +4 -15
  35. package/framework/standards/ai-agents/modalities-text-to-speech.md +2 -11
  36. package/framework/standards/ai-agents/modalities-vision.md +1 -18
  37. package/framework/standards/ai-agents/prompt-sources.md +0 -4
  38. package/framework/standards/architecture/code-comments.md +52 -16
  39. package/framework/standards/backend/integrations/neon-auth/neon-auth.md +63 -50
  40. package/framework/standards/frontend/design-system/ai-image-generation.md +5 -5
  41. package/framework/standards/integration/mcp/mcp-tools.md +48 -117
  42. package/framework/templates/code/dotnet/abstractions/result.cs +0 -2
  43. package/framework/templates/code/dotnet/ai-agents/AgentBootstrap.cs.template +26 -39
  44. package/framework/templates/code/dotnet/ai-agents/EmbeddingService.cs.template +28 -68
  45. package/framework/templates/code/dotnet/ai-agents/ModelRegistry.cs.template +99 -117
  46. package/framework/templates/code/dotnet/ai-agents/PromptRepository.cs.template +2 -44
  47. package/framework/templates/code/dotnet/ai-agents/ResilientToolMiddleware.cs.template +40 -61
  48. package/framework/templates/code/dotnet/ai-agents/VectorSearchTool.cs.template +54 -107
  49. package/framework/templates/code/dotnet/ai-agents/model-registry.json.template +53 -58
  50. package/framework/templates/code/dotnet/contracts/contracts-vsa.cs +192 -281
  51. package/framework/templates/code/dotnet/database/migration.cs +49 -83
  52. package/framework/templates/code/dotnet/database/vector-entity.cs +2 -46
  53. package/framework/templates/code/dotnet/extensions/result-extensions.cs +0 -2
  54. package/framework/templates/code/dotnet/feature/validator.cs.hbs +11 -15
  55. package/framework/templates/code/dotnet/jobs/agent.cs +3 -51
  56. package/framework/templates/code/dotnet/jobs/job.cs +2 -97
  57. package/framework/templates/code/dotnet/test.cs +2 -87
  58. package/framework/templates/code/typescript/contracts.ts +140 -167
  59. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Agents/AgentApi.cs +1 -48
  60. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Agents/AgentFactory.cs +3 -79
  61. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Agents/AgentFactoryOptions.cs +1 -70
  62. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Agents/AgentSpec.cs +1 -47
  63. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Agents/AgentSpecOptions.cs +2 -99
  64. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/AiKitAssemblyMarker.cs +0 -6
  65. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Conversation/ConversationStore.cs +3 -88
  66. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Conversation/IConversationStore.cs +1 -41
  67. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Conversation/InMemoryConversationStore.cs +0 -21
  68. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/CountingChatClient.cs +1 -25
  69. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/EvalAssertion.cs +2 -63
  70. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/EvalCacheMissException.cs +0 -30
  71. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/EvalCacheOptions.cs +1 -52
  72. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/EvalCacheStamp.cs +3 -78
  73. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/EvalFixture.cs +4 -109
  74. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/EvalMode.cs +0 -22
  75. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/EvalQualityEvaluators.cs +1 -36
  76. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/EvalScenario.cs +2 -57
  77. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/EvalSummary.cs +0 -75
  78. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/OfflineChatClient.cs +2 -59
  79. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/ShortPathResponseCache.cs +4 -111
  80. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/IMediaGenerator.cs +0 -34
  81. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/IMediaProvider.cs +1 -57
  82. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaArtifact.cs +0 -19
  83. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaDisclosure.cs +2 -74
  84. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaGenerator.cs +2 -33
  85. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaIdempotencyKey.cs +1 -43
  86. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaJob.cs +1 -96
  87. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaJobId.cs +0 -13
  88. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaJobState.cs +0 -27
  89. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaPricing.cs +0 -33
  90. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaProvenance.cs +0 -31
  91. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaRequest.cs +3 -75
  92. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaResult.cs +0 -42
  93. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaReview.cs +0 -39
  94. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaSeams.cs +1 -55
  95. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaStore.cs +3 -59
  96. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MorphMedia.cs +0 -46
  97. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/Providers/GoogleImageProvider.cs +3 -28
  98. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/Providers/OpenAIImageProvider.cs +7 -61
  99. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/Providers/VeoVideoProvider.cs +2 -37
  100. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Middleware/IUsageCostSink.cs +1 -23
  101. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Middleware/UsageCostMiddleware.cs +2 -82
  102. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Middleware/UsageCostRecord.cs +1 -68
  103. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Observability/MorphOpenTelemetryExtensions.cs +1 -62
  104. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Observability/MorphTelemetryOptions.cs +2 -62
  105. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Providers/IProviderClientFactory.cs +1 -25
  106. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Providers/ModelAlias.cs +0 -124
  107. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Providers/ModelRegistry.cs +1 -73
  108. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Rag/DeltaIngest.cs +1 -66
  109. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Rag/DeltaPlan.cs +0 -41
  110. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/AgentFactoryTests.cs +2 -112
  111. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/AgentSpecTests.cs +2 -43
  112. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/ConversationStoreTests.cs +5 -110
  113. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/DeltaIngestTests.cs +7 -103
  114. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Evals/EvalAssertionTests.cs +1 -42
  115. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Evals/EvalCacheMissTests.cs +1 -30
  116. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Evals/EvalCacheStampTests.cs +1 -19
  117. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Evals/EvalFailuresTests.cs +0 -48
  118. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Evals/EvalFixtureTests.cs +1 -29
  119. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Evals/EvalRefreshTests.cs +2 -38
  120. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Evals/EvalWorkspace.cs +1 -14
  121. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Evals/KitEvals.cs +4 -69
  122. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Evals/OfflineChatClientTests.cs +1 -10
  123. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Fakes/FakeChatClient.cs +1 -57
  124. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Fakes/FakeChatClientTests.cs +0 -26
  125. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Fakes/FakeClock.cs +1 -19
  126. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Fakes/FakeMediaProvider.cs +0 -32
  127. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Fakes/FakeProviderClientFactory.cs +0 -14
  128. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Fakes/FakeUsageCostSink.cs +0 -24
  129. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Fakes/InMemoryMediaStore.cs +0 -32
  130. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/MediaAccessibilityTests.cs +0 -37
  131. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/MediaAliasIsNotAnAgentTests.cs +0 -24
  132. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/MediaDisclosureTests.cs +0 -78
  133. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/MediaGeneratorTests.cs +0 -53
  134. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/MediaIdempotencyKeyTests.cs +0 -44
  135. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/MediaJobStateTests.cs +0 -44
  136. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/MediaReviewTests.cs +0 -19
  137. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/MediaStoreTests.cs +0 -24
  138. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/ModelRegistryTests.cs +6 -48
  139. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/SkeletonSmokeTests.cs +1 -13
  140. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/TelemetryTests.cs +2 -71
  141. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/UsageCostMiddlewareTests.cs +5 -100
  142. package/framework/templates/frontend/nextjs/Dockerfile.nextjs.hbs +39 -43
  143. package/framework/templates/frontend/nextjs/env.mjs.hbs +29 -32
  144. package/framework/templates/frontend/nextjs/page.tsx.hbs +21 -22
  145. package/framework/templates/frontend/nextjs/use-feature.ts.hbs +42 -54
  146. package/framework/templates/integrations/asaas-client.cs +332 -387
  147. package/framework/templates/integrations/asaas-webhook.cs +290 -351
  148. package/framework/templates/integrations/neon-auth-config.cs +9 -105
  149. package/framework/templates/project/validate.js +97 -120
  150. package/package.json +2 -2
  151. package/src/commands/dashboard/dashboard.js +80 -53
  152. package/src/commands/mcp/mcp-setup.js +37 -9
  153. package/src/commands/project/doctor.js +3 -5
  154. package/src/commands/project/init.js +6 -3
  155. package/src/commands/project/install-plugin-cmd.js +1 -1
  156. package/src/commands/project/update.js +5 -0
  157. package/src/dashboard/app/App.jsx +80 -16
  158. package/src/dashboard/app/components/ActivityFeed.jsx +172 -0
  159. package/src/dashboard/app/components/CommandPalette.jsx +155 -0
  160. package/src/dashboard/app/components/DetailPanel.jsx +47 -11
  161. package/src/dashboard/app/components/EntityLink.jsx +55 -0
  162. package/src/dashboard/app/components/ErrorBoundary.jsx +54 -0
  163. package/src/dashboard/app/components/FlowGraph.jsx +19 -17
  164. package/src/dashboard/app/components/KnowledgeMarkdown.jsx +53 -0
  165. package/src/dashboard/app/components/Markdown.jsx +47 -0
  166. package/src/dashboard/app/components/PhaseRail.jsx +111 -0
  167. package/src/dashboard/app/components/SearchFilter.jsx +40 -22
  168. package/src/dashboard/app/components/Sidebar.jsx +146 -37
  169. package/src/dashboard/app/hooks/useMorphQuery.js +54 -0
  170. package/src/dashboard/app/hooks/usePref.js +38 -0
  171. package/src/dashboard/app/lib/format.js +69 -0
  172. package/src/dashboard/app/lib/phases.js +56 -0
  173. package/src/dashboard/app/lib/project.js +50 -0
  174. package/src/dashboard/app/pages/Activity.jsx +24 -0
  175. package/src/dashboard/app/pages/AgentMap.jsx +371 -370
  176. package/src/dashboard/app/pages/FeatureDetail.jsx +604 -0
  177. package/src/dashboard/app/pages/Features.jsx +400 -0
  178. package/src/dashboard/app/pages/Guide.jsx +146 -0
  179. package/src/dashboard/app/pages/HookInspector.jsx +357 -322
  180. package/src/dashboard/app/pages/PhasePipeline.jsx +277 -408
  181. package/src/dashboard/app/pages/Portfolio.jsx +156 -0
  182. package/src/dashboard/app/pages/Rubrics.jsx +101 -0
  183. package/src/dashboard/app/pages/RulesMap.jsx +300 -273
  184. package/src/dashboard/app/pages/SkillsLibrary.jsx +483 -366
  185. package/src/dashboard/app/pages/Standards.jsx +407 -332
  186. package/src/dashboard/app/styles/index.css +187 -47
  187. package/src/dashboard/index.html +14 -12
  188. package/src/dashboard/package.json +32 -24
  189. package/src/dashboard/scanner/activity-scanner.js +351 -0
  190. package/src/dashboard/scanner/agents-scanner.js +59 -1
  191. package/src/dashboard/scanner/docs-scanner.js +59 -0
  192. package/src/dashboard/scanner/feature-status.js +10 -0
  193. package/src/dashboard/scanner/features-scanner.js +360 -0
  194. package/src/dashboard/scanner/index.js +14 -7
  195. package/src/dashboard/scanner/phases-scanner.js +14 -15
  196. package/src/dashboard/scanner/portfolio.js +153 -0
  197. package/src/dashboard/scanner/project-api.js +195 -0
  198. package/src/dashboard/scanner/rules-scanner.js +42 -37
  199. package/src/dashboard/scanner/skills-scanner.js +105 -43
  200. package/src/dashboard/scanner/standards-scanner.js +2 -0
  201. package/src/dashboard/vite-plugin-morph-data.js +134 -17
  202. package/src/lib/detectors/claude-config-detector.js +2 -7
  203. package/src/lib/detectors/index.js +5 -1
  204. package/src/lib/evaluator-report.js +22 -0
  205. package/src/lib/generators/settings-generator.js +208 -209
  206. package/src/lib/installers/mcp-installer.js +724 -719
  207. package/src/lib/installers/memory-installer.js +1 -2
  208. package/src/lib/projects/registry.js +154 -0
  209. package/src/lib/validators/code-budget/code-budget-validator.js +32 -4
  210. package/src/scripts/install-plugin.js +1 -1
  211. package/src/scripts/setup-infra.js +2 -4
  212. package/src/utils/agents-installer.js +57 -12
  213. package/src/utils/banner.js +1 -1
  214. package/src/commands/index.js +0 -13
  215. package/src/commands/project/checkpoint.js +0 -209
  216. package/src/core/state/phase-state-machine.js +0 -197
  217. package/src/dashboard/app/hooks/useDetailPanel.js +0 -15
  218. package/src/dashboard/app/pages/LiveState.jsx +0 -206
  219. package/src/dashboard/scanner/squads-scanner.js +0 -13
  220. package/src/dashboard/scanner/state-scanner.js +0 -85
  221. package/src/lib/generators/index.js +0 -10
  222. package/src/lib/hooks/hook-executor.js +0 -167
  223. package/src/lib/validators/checkpoint-persistence.js +0 -39
  224. package/src/lib/validators/shared/emit-validator-dispatch.js +0 -14
  225. package/src/lib/validators/shared/index.js +0 -12
  226. package/src/lib/validators/shared/issue-counter.js +0 -14
  227. package/src/lib/validators/shared/result-formatter.js +0 -124
@@ -1,167 +1,140 @@
1
- // ============================================================
2
- // CONTRACTS: {{titleCase FEATURE_NAME}}
3
- // Stack: Next.js + Neon
4
- // Generated by MORPH Framework
5
- // Date: {{DATE}}
6
- // ============================================================
7
-
8
- // ----- Neon Config -----
9
-
10
- export interface NeonConfig {
11
- connectionString: string;
12
- }
13
-
14
- // ----- API Client Types -----
15
-
16
- export interface ApiClientConfig {
17
- baseUrl: string;
18
- getAccessToken: () => Promise<string | null>;
19
- }
20
-
21
- export interface ApiError {
22
- message: string;
23
- code: string;
24
- statusCode: number;
25
- details?: Record<string, string[]>;
26
- }
27
-
28
- export type ApiResult<T> =
29
- | { success: true; data: T }
30
- | { success: false; error: ApiError };
31
-
32
- // ----- Pagination -----
33
-
34
- export interface PaginationQuery {
35
- page?: number;
36
- pageSize?: number;
37
- }
38
-
39
- export interface PagedResult<T> {
40
- items: T[];
41
- totalCount: number;
42
- page: number;
43
- pageSize: number;
44
- totalPages: number;
45
- hasNext: boolean;
46
- hasPrevious: boolean;
47
- }
48
-
49
- // ----- Database Client Type Aliases -----
50
- // Generated by your ORM (Drizzle or Prisma) from your Neon PostgreSQL schema
51
-
52
- export type Tables<T extends keyof Database["public"]["Tables"]> =
53
- Database["public"]["Tables"][T]["Row"];
54
-
55
- export type Insertable<T extends keyof Database["public"]["Tables"]> =
56
- Database["public"]["Tables"][T]["Insert"];
57
-
58
- export type Updatable<T extends keyof Database["public"]["Tables"]> =
59
- Database["public"]["Tables"][T]["Update"];
60
-
61
- // ----- Database Schema (placeholder - replace with generated types) -----
62
-
63
- export interface Database {
64
- public: {
65
- Tables: {
66
- {{FEATURE_NAME}}: {
67
- Row: {
68
- id: string;
69
- name: string;
70
- user_id: string;
71
- status: {{pascalCase FEATURE_NAME}}Status;
72
- created_at: string;
73
- updated_at: string | null;
74
- };
75
- Insert: {
76
- id?: string;
77
- name: string;
78
- user_id?: string;
79
- status?: {{pascalCase FEATURE_NAME}}Status;
80
- created_at?: string;
81
- updated_at?: string | null;
82
- };
83
- Update: {
84
- id?: string;
85
- name?: string;
86
- user_id?: string;
87
- status?: {{pascalCase FEATURE_NAME}}Status;
88
- created_at?: string;
89
- updated_at?: string | null;
90
- };
91
- };
92
- };
93
- Views: Record<string, never>;
94
- Functions: Record<string, never>;
95
- Enums: {
96
- {{FEATURE_NAME}}_status: {{pascalCase FEATURE_NAME}}Status;
97
- };
98
- };
99
- }
100
-
101
- // ----- Feature Types -----
102
-
103
- export type {{pascalCase FEATURE_NAME}}Status =
104
- | "draft"
105
- | "active"
106
- | "completed"
107
- | "archived"
108
- | "failed"
109
- | "cancelled";
110
-
111
- export interface {{pascalCase FEATURE_NAME}} {
112
- id: string;
113
- name: string;
114
- userId: string;
115
- status: {{pascalCase FEATURE_NAME}}Status;
116
- createdAt: string;
117
- updatedAt: string | null;
118
- }
119
-
120
- export interface Create{{pascalCase FEATURE_NAME}}Input {
121
- name: string;
122
- // Add other required fields
123
- }
124
-
125
- export interface Update{{pascalCase FEATURE_NAME}}Input {
126
- name?: string;
127
- // Add other updatable fields
128
- }
129
-
130
- // ----- Storage Types -----
131
-
132
- export interface StorageUpload {
133
- bucket: string;
134
- path: string;
135
- file: File;
136
- contentType?: string;
137
- }
138
-
139
- export interface StorageFile {
140
- id: string;
141
- name: string;
142
- bucket: string;
143
- path: string;
144
- publicUrl: string;
145
- size: number;
146
- contentType: string;
147
- createdAt: string;
148
- }
149
-
150
- // ----- Auth Types -----
151
-
152
- export interface AuthUser {
153
- id: string;
154
- email: string;
155
- displayName: string | null;
156
- avatarUrl: string | null;
157
- }
158
-
159
- export interface AuthSession {
160
- user: AuthUser;
161
- accessToken: string;
162
- expiresAt: number;
163
- }
164
-
165
- // ----- Form Schemas (use with zod) -----
166
- // Define zod schemas in component files, not here.
167
- // This file is for type definitions only.
1
+ // {{titleCase FEATURE_NAME}} contracts, generated {{DATE}}
2
+
3
+ export interface NeonConfig {
4
+ connectionString: string;
5
+ }
6
+
7
+ export interface ApiClientConfig {
8
+ baseUrl: string;
9
+ getAccessToken: () => Promise<string | null>;
10
+ }
11
+
12
+ export interface ApiError {
13
+ message: string;
14
+ code: string;
15
+ statusCode: number;
16
+ details?: Record<string, string[]>;
17
+ }
18
+
19
+ export type ApiResult<T> =
20
+ | { success: true; data: T }
21
+ | { success: false; error: ApiError };
22
+
23
+ export interface PaginationQuery {
24
+ page?: number;
25
+ pageSize?: number;
26
+ }
27
+
28
+ export interface PagedResult<T> {
29
+ items: T[];
30
+ totalCount: number;
31
+ page: number;
32
+ pageSize: number;
33
+ totalPages: number;
34
+ hasNext: boolean;
35
+ hasPrevious: boolean;
36
+ }
37
+
38
+ export type Tables<T extends keyof Database["public"]["Tables"]> =
39
+ Database["public"]["Tables"][T]["Row"];
40
+
41
+ export type Insertable<T extends keyof Database["public"]["Tables"]> =
42
+ Database["public"]["Tables"][T]["Insert"];
43
+
44
+ export type Updatable<T extends keyof Database["public"]["Tables"]> =
45
+ Database["public"]["Tables"][T]["Update"];
46
+
47
+ // Placeholder: replace with the types your ORM (Drizzle or Prisma) generates from the Neon schema.
48
+ export interface Database {
49
+ public: {
50
+ Tables: {
51
+ {{FEATURE_NAME}}: {
52
+ Row: {
53
+ id: string;
54
+ name: string;
55
+ user_id: string;
56
+ status: {{pascalCase FEATURE_NAME}}Status;
57
+ created_at: string;
58
+ updated_at: string | null;
59
+ };
60
+ Insert: {
61
+ id?: string;
62
+ name: string;
63
+ user_id?: string;
64
+ status?: {{pascalCase FEATURE_NAME}}Status;
65
+ created_at?: string;
66
+ updated_at?: string | null;
67
+ };
68
+ Update: {
69
+ id?: string;
70
+ name?: string;
71
+ user_id?: string;
72
+ status?: {{pascalCase FEATURE_NAME}}Status;
73
+ created_at?: string;
74
+ updated_at?: string | null;
75
+ };
76
+ };
77
+ };
78
+ Views: Record<string, never>;
79
+ Functions: Record<string, never>;
80
+ Enums: {
81
+ {{FEATURE_NAME}}_status: {{pascalCase FEATURE_NAME}}Status;
82
+ };
83
+ };
84
+ }
85
+
86
+ export type {{pascalCase FEATURE_NAME}}Status =
87
+ | "draft"
88
+ | "active"
89
+ | "completed"
90
+ | "archived"
91
+ | "failed"
92
+ | "cancelled";
93
+
94
+ export interface {{pascalCase FEATURE_NAME}} {
95
+ id: string;
96
+ name: string;
97
+ userId: string;
98
+ status: {{pascalCase FEATURE_NAME}}Status;
99
+ createdAt: string;
100
+ updatedAt: string | null;
101
+ }
102
+
103
+ export interface Create{{pascalCase FEATURE_NAME}}Input {
104
+ name: string;
105
+ }
106
+
107
+ export interface Update{{pascalCase FEATURE_NAME}}Input {
108
+ name?: string;
109
+ }
110
+
111
+ export interface StorageUpload {
112
+ bucket: string;
113
+ path: string;
114
+ file: File;
115
+ contentType?: string;
116
+ }
117
+
118
+ export interface StorageFile {
119
+ id: string;
120
+ name: string;
121
+ bucket: string;
122
+ path: string;
123
+ publicUrl: string;
124
+ size: number;
125
+ contentType: string;
126
+ createdAt: string;
127
+ }
128
+
129
+ export interface AuthUser {
130
+ id: string;
131
+ email: string;
132
+ displayName: string | null;
133
+ avatarUrl: string | null;
134
+ }
135
+
136
+ export interface AuthSession {
137
+ user: AuthUser;
138
+ accessToken: string;
139
+ expiresAt: number;
140
+ }
@@ -1,65 +1,18 @@
1
1
  namespace Morph.AiKit.Agents;
2
2
 
3
- /// <summary>
4
- /// Protocolo pelo qual um modelo e alcancado. E o campo <c>api:</c> por alias que a
5
- /// issue #92 exige: a MESMA familia de modelos e atendida por dois protocolos
6
- /// diferentes, e qual deles vale e decisao de configuracao — nunca folclore espalhado
7
- /// por condicional no meio do codigo.
8
- /// </summary>
9
- /// <remarks>
10
- /// <para>
11
- /// <see cref="Responses"/> e <b>0 de proposito</b>: <c>default(AgentApi)</c> e a Responses
12
- /// API porque essa e a decisao da casa (Responses por padrao, Chat Completions como
13
- /// opt-in explicito por alias). Um alias que omite <c>api:</c> no
14
- /// <c>model-registry.v2.json</c> cai em Responses; usar Chat Completions exige escrever
15
- /// <c>"api": "chat"</c> — ou seja, exige alguem assumir a escolha por escrito.
16
- /// </para>
17
- /// <para>
18
- /// O enum descreve a escolha ENTRE OS DOIS PROTOCOLOS DA OpenAI. Provider que expoe um
19
- /// unico protocolo (Google, Ollama) ignora o campo, e por isso declara — ou omite,
20
- /// caindo em — <see cref="Responses"/>: escrever <c>chat</c> ali sugeriria uma escolha
21
- /// que naquele provider nao existe.
22
- /// </para>
23
- /// </remarks>
24
3
  public enum AgentApi
25
4
  {
26
- /// <summary>Responses API — o padrao da casa. Valor 0, logo <c>default(AgentApi)</c>.</summary>
5
+ // 0 de proposito: default(AgentApi) e alias sem 'api:' caem em Responses; Chat e opt-in escrito.
27
6
  Responses = 0,
28
7
 
29
- /// <summary>
30
- /// Chat Completions — opt-in explicito por alias. Carrega limites que a Responses API
31
- /// nao tem; ver <c>Morph.AiKit.Providers.ModelAliasConstraints</c>.
32
- /// </summary>
33
8
  Chat = 1,
34
9
 
35
- /// <summary>
36
- /// Images — geracao/edicao de imagem. <b>Nao e um protocolo de conversa</b>: um alias
37
- /// com este <c>api</c> e recusado pela <c>AgentFactory</c>, com erro nomeado.
38
- /// </summary>
39
- /// <remarks>
40
- /// Um registry so, um vocabulario so de alias: quem procura "qual modelo este projeto
41
- /// usa" encontra o de imagem no mesmo lugar que o de chat. A alternativa era um
42
- /// <c>media-registry.json</c> separado — duas verdades sobre o mesmo fato.
43
- /// </remarks>
44
10
  Images = 2,
45
11
 
46
- /// <summary>
47
- /// Videos — geracao de video. Mesma regra de <see cref="Images"/>: alias de midia nao
48
- /// vira agente.
49
- /// </summary>
50
12
  Videos = 3,
51
13
  }
52
14
 
53
- /// <summary>Predicados sobre <see cref="AgentApi"/>.</summary>
54
15
  public static class AgentApiExtensions
55
16
  {
56
- /// <summary>
57
- /// Se o protocolo e de MIDIA (imagem ou video) e portanto nao fala conversa.
58
- /// </summary>
59
- /// <remarks>
60
- /// Escrito uma vez, aqui, porque duas copias deste predicado sao como a
61
- /// <c>AgentFactory</c> e o <c>ModelRegistry</c> passariam a discordar sobre o mesmo
62
- /// alias.
63
- /// </remarks>
64
17
  public static bool IsMedia(this AgentApi api) => api is AgentApi.Images or AgentApi.Videos;
65
18
  }
@@ -5,48 +5,11 @@ using Morph.AiKit.Providers;
5
5
 
6
6
  namespace Morph.AiKit.Agents;
7
7
 
8
- /// <summary>
9
- /// Transforma uma <see cref="AgentSpec"/> (o agente como dado) num
10
- /// <see cref="AIAgent"/> pronto para rodar. E o unico lugar do kit que conhece a ORDEM do
11
- /// pipeline.
12
- /// </summary>
13
- /// <remarks>
14
- /// <para><b>A ordem, de fora para dentro, e o contrato desta classe:</b></para>
15
- /// <code>
16
- /// OpenTelemetryAgent span invoke_agent — cobre a invocacao inteira (T12)
17
- /// +- ChatClientAgent UseProvidedChatClientAsIs = true: o pipeline abaixo e nosso
18
- /// +- timeout TimeoutSeconds vira CancellationToken
19
- /// +- usage-cost ve UMA resposta com o uso ja somado das voltas (T11)
20
- /// +- FunctionInvoking MaxToolIterations / AllowConcurrentToolInvocation
21
- /// +- telemetria de chat span chat, ABAIXO do FICC (T12)
22
- /// +- cliente do provider memoizado pelo ModelRegistry
23
- /// </code>
24
- /// <para>
25
- /// Cada posicao foi <b>medida</b> contra o pin, nao herdada de folclore. Acima do FICC o
26
- /// middleware de custo recebe o uso agregado (10/4 + 30/6 chegam como 40/10); abaixo dele
27
- /// receberia uma resposta por volta, e ainda leria um <c>UsageDetails</c> que o FICC muta
28
- /// para acumular. A telemetria de chat fica abaixo do FICC porque o MAF 1.20.0 escreve, na
29
- /// documentacao do proprio slot que ele reserva, que so assim o span de chat fecha antes
30
- /// das tools e o <c>invoke_agent</c> vira raiz.
31
- /// </para>
32
- /// <para>
33
- /// <b>Por que <c>UseProvidedChatClientAsIs = true</c>:</b> com o default, o
34
- /// <c>ChatClientAgent</c> monta ele mesmo o FICC — e nao ha onde ajustar
35
- /// <c>MaximumIterationsPerRequest</c> nem onde encaixar o custo entre o FICC e o cliente.
36
- /// O preco medido dessa escolha e que o slot de telemetria que o MAF reservaria deixa de
37
- /// existir: sem a T12 ligada, um agente desta fabrica emite <c>invoke_agent</c> e
38
- /// <b>nenhum</b> span de chat. E por isso que a telemetria de chat e um encaixe nomeado, e
39
- /// nao um detalhe opcional.
40
- /// </para>
41
- /// </remarks>
42
8
  public sealed class AgentFactory
43
9
  {
44
10
  private readonly ModelRegistry _registry;
45
11
  private readonly AgentFactoryOptions _options;
46
12
 
47
- /// <summary>Cria a fabrica sobre um registry ja carregado.</summary>
48
- /// <param name="registry">Fonte unica de alias, protocolo e tarifa.</param>
49
- /// <param name="options">Infraestrutura e encaixes. Nulo = nenhum encaixe preenchido.</param>
50
13
  public AgentFactory(ModelRegistry registry, AgentFactoryOptions? options = null)
51
14
  {
52
15
  ArgumentNullException.ThrowIfNull(registry);
@@ -55,15 +18,6 @@ public sealed class AgentFactory
55
18
  _options = options ?? new AgentFactoryOptions();
56
19
  }
57
20
 
58
- /// <summary>
59
- /// Materializa a spec. Alias desconhecido, limite de alias violado ou troca de
60
- /// protocolo sem seletor sao recusas <b>na construcao</b> — nunca um agente meio certo.
61
- /// </summary>
62
- /// <remarks>
63
- /// Recusar aqui e falha de composicao, nao excecao como fluxo de controle: acontece uma
64
- /// vez, na montagem, e seguir adiante seria seguir sem regua. Quem quiser inspecionar
65
- /// antes chama <c>registry.Resolve(alias).CheckRequest(...)</c>, que e Result.
66
- /// </remarks>
67
21
  public AIAgent Create(AgentSpec spec)
68
22
  {
69
23
  ArgumentNullException.ThrowIfNull(spec);
@@ -71,11 +25,6 @@ public sealed class AgentFactory
71
25
  var alias = _registry.Resolve(spec.Alias);
72
26
  var api = spec.ResolveApi(alias.Api);
73
27
 
74
- // Alias de MIDIA nao vira agente, e a recusa e aqui, na construcao. Sem ela, um
75
- // alias de imagem passado por engano viraria um agente de chat apontando para um
76
- // modelo que nao fala chat: a falha apareceria tarde, no primeiro turno, com uma
77
- // mensagem do provider que nao diz o que aconteceu. E a companheira obrigatoria de
78
- // AgentApi.Images/Videos existirem — enum novo sem recusa e uma armadilha nova.
79
28
  if (alias.Api.IsMedia() || api.IsMedia())
80
29
  {
81
30
  throw AgentFactoryException.MediaAliasIsNotAnAgent(spec.Alias, alias.Api.IsMedia() ? alias.Api : api);
@@ -98,6 +47,7 @@ public sealed class AgentFactory
98
47
  Name = spec.Name,
99
48
  Description = spec.Description,
100
49
  ChatOptions = BuildChatOptions(spec, alias),
50
+ // Com o default o ChatClientAgent monta o proprio FICC, sem MaximumIterationsPerRequest nem slot para o custo.
101
51
  UseProvidedChatClientAsIs = true,
102
52
  };
103
53
 
@@ -112,12 +62,6 @@ public sealed class AgentFactory
112
62
  : agent;
113
63
  }
114
64
 
115
- /// <summary>
116
- /// As opcoes de requisicao do agente. <c>ModelId</c> vem do alias — a spec nunca cita
117
- /// modelo. <c>Tools</c> e <c>ResponseFormat</c> entram antes de
118
- /// <see cref="AgentSpecOptions.ApplyTo"/>, que por contrato nao sobrescreve o que ja
119
- /// foi definido.
120
- /// </summary>
121
65
  private static ChatOptions BuildChatOptions(AgentSpec spec, ModelAlias alias)
122
66
  {
123
67
  var options = new ChatOptions
@@ -151,6 +95,8 @@ public sealed class AgentFactory
151
95
  : throw AgentFactoryException.ProtocolWithoutSelector(alias.Name, alias.Api, api);
152
96
  }
153
97
 
98
+ // A ordem e o contrato: o custo fica ACIMA do FICC para ver o uso ja somado das voltas, e a
99
+ // telemetria de chat ABAIXO dele porque so assim o span de chat fecha antes das tools (MAF 1.20.0).
154
100
  private IChatClient BuildChatPipeline(IChatClient leaf, AgentSpec spec, ModelAlias alias)
155
101
  {
156
102
  var builder = leaf.AsBuilder();
@@ -186,11 +132,6 @@ public sealed class AgentFactory
186
132
  return builder.Build(_options.ServiceProvider);
187
133
  }
188
134
 
189
- /// <summary>
190
- /// Realiza <see cref="AgentSpecOptions.TimeoutSeconds"/>. Vive aqui, privado, porque e
191
- /// a traducao de UMA opcao para o <see cref="CancellationToken"/> que o pipeline ja
192
- /// carrega — e nao um conceito que alguem deva compor por fora.
193
- /// </summary>
194
135
  private sealed class TimeoutChatClient(IChatClient inner, TimeSpan timeout) : DelegatingChatClient(inner)
195
136
  {
196
137
  public override async Task<ChatResponse> GetResponseAsync(
@@ -222,43 +163,31 @@ public sealed class AgentFactory
222
163
  }
223
164
  }
224
165
 
225
- /// <summary>Motivo de uma recusa da <see cref="AgentFactory"/>.</summary>
226
166
  public enum AgentFactoryError
227
167
  {
228
- /// <summary>A requisicao viola um limite declarado no alias, com procedencia.</summary>
229
168
  ConstraintViolated = 0,
230
169
 
231
- /// <summary>A spec pede um protocolo diferente do alias e nao ha seletor de cliente.</summary>
232
170
  ProtocolWithoutSelector = 1,
233
171
 
234
- /// <summary>O seletor de cliente devolveu nulo.</summary>
235
172
  NoChatClient = 2,
236
173
 
237
- /// <summary>O alias e de midia (<c>api: images</c> ou <c>api: videos</c>) e nao fala conversa.</summary>
238
174
  MediaAliasIsNotAnAgent = 3,
239
175
  }
240
176
 
241
- /// <summary>
242
- /// Recusa de composicao da <see cref="AgentFactory"/>. <c>sealed</c> e discriminada por
243
- /// <see cref="Reason"/>: quem trata precisa do motivo, nao de herdar do tipo.
244
- /// </summary>
245
177
  public sealed class AgentFactoryException : InvalidOperationException
246
178
  {
247
179
  private AgentFactoryException(AgentFactoryError reason, string message)
248
180
  : base(message)
249
181
  => Reason = reason;
250
182
 
251
- /// <summary>Por que a fabrica recusou.</summary>
252
183
  public AgentFactoryError Reason { get; }
253
184
 
254
- /// <summary>A requisicao viola limites do alias. A mensagem traz cada violacao com sua procedencia.</summary>
255
185
  public static AgentFactoryException ConstraintViolated(string alias, IReadOnlyList<string> violations)
256
186
  => new(
257
187
  AgentFactoryError.ConstraintViolated,
258
188
  $"alias '{alias}': a spec viola limite(s) declarado(s) do alias e o agente NAO foi criado. " +
259
189
  string.Join(" | ", violations));
260
190
 
261
- /// <summary>Divergencia de protocolo sem seletor que saiba construir o outro cliente.</summary>
262
191
  public static AgentFactoryException ProtocolWithoutSelector(string alias, AgentApi aliasApi, AgentApi specApi)
263
192
  => new(
264
193
  AgentFactoryError.ProtocolWithoutSelector,
@@ -268,10 +197,6 @@ public sealed class AgentFactoryException : InvalidOperationException
268
197
  "alias com o api pedido no model-registry.v2.json, ou preencha " +
269
198
  $"{nameof(AgentFactoryOptions)}.{nameof(AgentFactoryOptions.ChatClientSelector)}.");
270
199
 
271
- /// <summary>
272
- /// O alias e de midia. Recusa nomeada, na construcao — nunca um agente que aponta para
273
- /// um modelo que nao fala chat.
274
- /// </summary>
275
200
  public static AgentFactoryException MediaAliasIsNotAnAgent(string alias, AgentApi api)
276
201
  => new(
277
202
  AgentFactoryError.MediaAliasIsNotAnAgent,
@@ -280,7 +205,6 @@ public sealed class AgentFactoryException : InvalidOperationException
280
205
  $"{nameof(Morph.AiKit.Media.IMediaGenerator)}.{nameof(Morph.AiKit.Media.IMediaGenerator.EnqueueAsync)}, " +
281
206
  "que devolve um id de job e nunca bytes. Ver ai-agents/media-pipeline.md.");
282
207
 
283
- /// <summary>O seletor devolveu nulo — nao ha cliente para o par alias/protocolo.</summary>
284
208
  public static AgentFactoryException NoChatClient(string alias, AgentApi api)
285
209
  => new(
286
210
  AgentFactoryError.NoChatClient,
@@ -5,87 +5,18 @@ using Morph.AiKit.Providers;
5
5
 
6
6
  namespace Morph.AiKit.Agents;
7
7
 
8
- /// <summary>
9
- /// O que a <see cref="AgentFactory"/> precisa saber que NAO esta na
10
- /// <see cref="AgentSpec"/>: infraestrutura do processo (log, DI) e os tres encaixes do
11
- /// pipeline que outras tasks preenchem.
12
- /// </summary>
13
- /// <remarks>
14
- /// <para>
15
- /// <b>Por que encaixes e nao dependencias diretas:</b> a ORDEM do pipeline e do kit — ela
16
- /// esta escrita, medida e testada dentro da <see cref="AgentFactory"/>. O CONTEUDO de cada
17
- /// posicao e de quem tem o tipo: o middleware de custo mora na T11 e a telemetria na T12.
18
- /// Se a fabrica referenciasse os dois diretamente, ou ela nasceria depois deles, ou eles
19
- /// nasceriam dentro dela. Com encaixe nomeado, a fabrica continua dona do lugar e cada
20
- /// task continua dona do que ocupa o lugar.
21
- /// </para>
22
- /// <para>
23
- /// Encaixe nulo = posicao vazia. Um agente sem custo e sem telemetria e um agente valido,
24
- /// nao um agente pela metade.
25
- /// </para>
26
- /// </remarks>
27
8
  public sealed record AgentFactoryOptions
28
9
  {
29
- /// <summary>
30
- /// Fabrica de log repassada ao <c>FunctionInvokingChatClient</c> e ao
31
- /// <c>ChatClientAgent</c>. Nula = sem log, que e o default do MAF.
32
- /// </summary>
33
10
  public ILoggerFactory? LoggerFactory { get; init; }
34
11
 
35
- /// <summary>
36
- /// Container usado para resolver servicos ao montar os pipelines. Nulo = os builders
37
- /// do <c>Microsoft.Extensions.AI</c> usam o provider vazio deles.
38
- /// </summary>
39
12
  public IServiceProvider? ServiceProvider { get; init; }
40
13
 
41
- /// <summary>
42
- /// De onde sai o <see cref="IChatClient"/> quando o protocolo efetivo NAO e o do alias.
43
- /// </summary>
44
- /// <remarks>
45
- /// <para>
46
- /// O <c>ModelRegistry</c> memoiza <b>um</b> cliente por alias, construido pela
47
- /// <c>IProviderClientFactory</c> a partir do <c>api:</c> daquele alias. Logo, uma spec
48
- /// que pede Chat Completions num alias declarado <c>responses</c> nao pode ser servida
49
- /// pelo cliente memoizado — ele fala o outro protocolo. Sem este seletor a fabrica
50
- /// <b>recusa</b> a combinacao, nomeando os dois protocolos, em vez de devolver um agente
51
- /// que diz falar um protocolo e fala outro.
52
- /// </para>
53
- /// <para>
54
- /// Nulo (o normal) = todo agente usa o cliente memoizado do alias, e
55
- /// <see cref="AgentSpec.Api"/> divergente vira recusa. Preenchido, recebe o alias e o
56
- /// protocolo <b>efetivo</b> (ja resolvido por <see cref="AgentSpec.ResolveApi"/>) e
57
- /// devolve o cliente correspondente.
58
- /// </para>
59
- /// </remarks>
60
14
  public Func<ModelAlias, AgentApi, IChatClient>? ChatClientSelector { get; init; }
61
15
 
62
- /// <summary>
63
- /// Encaixe do middleware de custo (T11), <b>acima</b> do <c>FunctionInvokingChatClient</c>.
64
- /// Preencha com <c>(b, _, alias) =&gt; b.UseUsageCost(alias, sink)</c>.
65
- /// </summary>
66
- /// <remarks>
67
- /// A posicao e medida, nao opinada: acima do FICC o middleware ve <b>uma</b> resposta
68
- /// com o uso ja somado de todas as voltas de tool (medido: 40/10 num roteiro de duas
69
- /// voltas de 10/4 e 30/6); abaixo do FICC ele ve uma resposta por volta. Pior, o FICC
70
- /// <b>acumula no proprio objeto</b> <c>UsageDetails</c> da primeira volta — um sink que
71
- /// guardasse a referencia abaixo do FICC leria valores que mudaram depois.
72
- /// </remarks>
16
+ // Abaixo do FICC um sink veria uma resposta por volta, e o FICC muta o UsageDetails da primeira volta para acumular.
73
17
  public Func<ChatClientBuilder, AgentSpec, ModelAlias, ChatClientBuilder>? ConfigureUsageCost { get; init; }
74
18
 
75
- /// <summary>
76
- /// Encaixe da telemetria de chat (T12), <b>abaixo</b> do <c>FunctionInvokingChatClient</c>
77
- /// e imediatamente acima do cliente do provider.
78
- /// </summary>
79
- /// <remarks>
80
- /// A posicao e exigencia escrita do proprio MAF 1.20.0: com a instrumentacao abaixo do
81
- /// FICC o span de chat fecha <b>antes</b> de as tools rodarem, o que deixa o
82
- /// <c>invoke_agent</c> como span raiz e permite ao FICC emitir <c>execute_tool</c>.
83
- /// </remarks>
84
19
  public Func<ChatClientBuilder, AgentSpec, ModelAlias, ChatClientBuilder>? ConfigureChatTelemetry { get; init; }
85
20
 
86
- /// <summary>
87
- /// Encaixe da telemetria de agente (T12) — o span mais externo, que cobre a invocacao
88
- /// inteira. Preencha com <c>(b, _, _) =&gt; b.UseMorphTelemetry(telemetryOptions)</c>.
89
- /// </summary>
90
21
  public Func<AIAgentBuilder, AgentSpec, ModelAlias, AIAgentBuilder>? ConfigureAgentTelemetry { get; init; }
91
22
  }