@polymorphism-tech/morph-spec 8.38.0 → 8.41.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/CLAUDE.md +20 -9
- package/README.md +2 -2
- package/bin/morph-spec.js +60 -43
- package/claude-plugin.json +1 -1
- package/docs/CHEATSHEET.md +1 -1
- package/docs/QUICKSTART.md +1 -1
- package/framework/CLAUDE.md +4 -3
- package/framework/MORPH.md +10 -9
- package/framework/agents.json +43 -26
- package/framework/docs/CLI.md +7 -5
- package/framework/evals/rubrics/code-quality.md +4 -4
- package/framework/evals/rubrics/condensed.md +2 -2
- package/framework/hooks/README.md +1 -1
- package/framework/hooks/claude-code/core/telemetry-log.js +39 -8
- package/framework/hooks/claude-code/core/worktree-create.js +22 -6
- package/framework/hooks/shared/git-paths.js +38 -5
- package/framework/mcp/registry.json +58 -66
- package/framework/rules/infrastructure-standards.md +0 -1
- package/framework/rules/morph-workflow.md +9 -4
- package/framework/skills/core/create-umbraco-lp/SKILL.md +1 -1
- package/framework/skills/core/migrate-lp-to-umbraco/SKILL.md +1 -1
- package/framework/skills/core/morph-apply/SKILL.md +59 -25
- package/framework/skills/core/morph-brainstorming/SKILL.md +1 -1
- package/framework/skills/core/morph-eval/SKILL.md +1 -1
- package/framework/skills/core/morph-hotfix/SKILL.md +2 -2
- package/framework/skills/core/morph-implement/SKILL.md +48 -24
- package/framework/skills/core/morph-media/SKILL.md +2 -2
- package/framework/skills/core/morph-plan/SKILL.md +10 -3
- package/framework/skills/core/morph-proposal/SKILL.md +1 -1
- package/framework/skills/core/morph-review/SKILL.md +1 -1
- package/framework/skills/core/morph-stack-scan/SKILL.md +1 -1
- package/framework/skills/core/morph-standards/SKILL.md +1 -1
- package/framework/skills/core/morph-uiux/SKILL.md +7 -6
- package/framework/standards/PROVENANCE.json +4 -4
- package/framework/standards/STANDARDS.json +9 -9
- package/framework/standards/ai-agents/context-providers.md +16 -26
- package/framework/standards/ai-agents/durable-workflows-hitl.md +15 -21
- package/framework/standards/ai-agents/modalities-image-gen.md +21 -25
- package/framework/standards/ai-agents/modalities-speech-to-text.md +4 -15
- package/framework/standards/ai-agents/modalities-text-to-speech.md +2 -11
- package/framework/standards/ai-agents/modalities-vision.md +1 -18
- package/framework/standards/ai-agents/prompt-sources.md +0 -4
- package/framework/standards/architecture/code-comments.md +52 -16
- package/framework/standards/backend/dotnet/testing.md +4 -2
- package/framework/standards/backend/integrations/neon-auth/neon-auth.md +63 -50
- package/framework/standards/frontend/design-system/ai-image-generation.md +42 -28
- package/framework/standards/frontend/design-system/ai-video-generation.md +24 -9
- package/framework/standards/frontend/nextjs/testing.md +4 -2
- package/framework/standards/integration/mcp/mcp-tools.md +64 -126
- package/framework/templates/code/dotnet/abstractions/result.cs +0 -2
- package/framework/templates/code/dotnet/ai-agents/AgentBootstrap.cs.template +26 -39
- package/framework/templates/code/dotnet/ai-agents/EmbeddingService.cs.template +28 -68
- package/framework/templates/code/dotnet/ai-agents/ModelRegistry.cs.template +99 -117
- package/framework/templates/code/dotnet/ai-agents/PromptRepository.cs.template +2 -44
- package/framework/templates/code/dotnet/ai-agents/ResilientToolMiddleware.cs.template +40 -61
- package/framework/templates/code/dotnet/ai-agents/VectorSearchTool.cs.template +54 -107
- package/framework/templates/code/dotnet/ai-agents/model-registry.json.template +53 -58
- package/framework/templates/code/dotnet/contracts/contracts-vsa.cs +192 -281
- package/framework/templates/code/dotnet/database/migration.cs +49 -83
- package/framework/templates/code/dotnet/database/vector-entity.cs +2 -46
- package/framework/templates/code/dotnet/extensions/result-extensions.cs +0 -2
- package/framework/templates/code/dotnet/feature/validator.cs.hbs +11 -15
- package/framework/templates/code/dotnet/jobs/agent.cs +3 -51
- package/framework/templates/code/dotnet/jobs/job.cs +2 -97
- package/framework/templates/code/dotnet/test.cs +2 -87
- package/framework/templates/code/typescript/contracts.ts +140 -167
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Agents/AgentApi.cs +1 -48
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Agents/AgentFactory.cs +3 -79
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Agents/AgentFactoryOptions.cs +1 -70
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Agents/AgentSpec.cs +1 -47
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Agents/AgentSpecOptions.cs +2 -99
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/AiKitAssemblyMarker.cs +0 -6
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Conversation/ConversationStore.cs +3 -88
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Conversation/IConversationStore.cs +1 -41
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Conversation/InMemoryConversationStore.cs +0 -21
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/CountingChatClient.cs +1 -25
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/EvalAssertion.cs +2 -63
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/EvalCacheMissException.cs +0 -30
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/EvalCacheOptions.cs +1 -52
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/EvalCacheStamp.cs +3 -78
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/EvalFixture.cs +4 -109
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/EvalMode.cs +0 -22
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/EvalQualityEvaluators.cs +1 -36
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/EvalScenario.cs +2 -57
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/EvalSummary.cs +0 -75
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/OfflineChatClient.cs +2 -59
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/ShortPathResponseCache.cs +4 -111
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/IMediaGenerator.cs +0 -34
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/IMediaProvider.cs +1 -57
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaArtifact.cs +0 -19
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaDisclosure.cs +2 -74
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaGenerator.cs +2 -33
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaIdempotencyKey.cs +1 -43
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaJob.cs +1 -96
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaJobId.cs +0 -13
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaJobState.cs +0 -27
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaPricing.cs +0 -33
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaProvenance.cs +0 -31
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaRequest.cs +3 -75
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaResult.cs +0 -42
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaReview.cs +0 -39
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaSeams.cs +1 -55
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaStore.cs +3 -59
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MorphMedia.cs +0 -46
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/Providers/GoogleImageProvider.cs +3 -28
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/Providers/OpenAIImageProvider.cs +7 -61
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/Providers/VeoVideoProvider.cs +2 -37
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Middleware/IUsageCostSink.cs +1 -23
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Middleware/UsageCostMiddleware.cs +2 -82
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Middleware/UsageCostRecord.cs +1 -68
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Observability/MorphOpenTelemetryExtensions.cs +1 -62
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Observability/MorphTelemetryOptions.cs +2 -62
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Providers/IProviderClientFactory.cs +1 -25
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Providers/ModelAlias.cs +0 -124
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Providers/ModelRegistry.cs +1 -73
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Rag/DeltaIngest.cs +1 -66
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Rag/DeltaPlan.cs +0 -41
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/AgentFactoryTests.cs +2 -112
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/AgentSpecTests.cs +2 -43
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/ConversationStoreTests.cs +5 -110
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/DeltaIngestTests.cs +7 -103
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Evals/EvalAssertionTests.cs +1 -42
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Evals/EvalCacheMissTests.cs +1 -30
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Evals/EvalCacheStampTests.cs +1 -19
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Evals/EvalFailuresTests.cs +0 -48
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Evals/EvalFixtureTests.cs +1 -29
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Evals/EvalRefreshTests.cs +2 -38
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Evals/EvalWorkspace.cs +1 -14
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Evals/KitEvals.cs +4 -69
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Evals/OfflineChatClientTests.cs +1 -10
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Fakes/FakeChatClient.cs +1 -57
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Fakes/FakeChatClientTests.cs +0 -26
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Fakes/FakeClock.cs +1 -19
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Fakes/FakeMediaProvider.cs +0 -32
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Fakes/FakeProviderClientFactory.cs +0 -14
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Fakes/FakeUsageCostSink.cs +0 -24
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Fakes/InMemoryMediaStore.cs +0 -32
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/MediaAccessibilityTests.cs +0 -37
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/MediaAliasIsNotAnAgentTests.cs +0 -24
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/MediaDisclosureTests.cs +0 -78
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/MediaGeneratorTests.cs +0 -53
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/MediaIdempotencyKeyTests.cs +0 -44
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/MediaJobStateTests.cs +0 -44
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/MediaReviewTests.cs +0 -19
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/MediaStoreTests.cs +0 -24
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/ModelRegistryTests.cs +6 -48
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/SkeletonSmokeTests.cs +1 -13
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/TelemetryTests.cs +2 -71
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/UsageCostMiddlewareTests.cs +5 -100
- package/framework/templates/frontend/nextjs/Dockerfile.nextjs.hbs +39 -43
- package/framework/templates/frontend/nextjs/env.mjs.hbs +29 -32
- package/framework/templates/frontend/nextjs/page.tsx.hbs +21 -22
- package/framework/templates/frontend/nextjs/use-feature.ts.hbs +42 -54
- package/framework/templates/integrations/asaas-client.cs +332 -387
- package/framework/templates/integrations/asaas-webhook.cs +290 -351
- package/framework/templates/integrations/neon-auth-config.cs +9 -105
- package/framework/templates/project/validate.js +97 -120
- package/package.json +2 -2
- package/src/commands/dashboard/dashboard.js +80 -53
- package/src/commands/mcp/mcp-setup.js +37 -9
- package/src/commands/project/doctor.js +12 -6
- package/src/commands/project/init.js +6 -3
- package/src/commands/project/install-plugin-cmd.js +1 -1
- package/src/commands/project/update.js +5 -0
- package/src/commands/project/worktree.js +60 -4
- package/src/commands/state/gate-check.js +5 -0
- package/src/commands/tasks/dag.js +27 -4
- package/src/commands/validation/verify.js +22 -38
- package/src/dashboard/app/App.jsx +80 -16
- package/src/dashboard/app/components/ActivityFeed.jsx +172 -0
- package/src/dashboard/app/components/CommandPalette.jsx +155 -0
- package/src/dashboard/app/components/DetailPanel.jsx +47 -11
- package/src/dashboard/app/components/EntityLink.jsx +55 -0
- package/src/dashboard/app/components/ErrorBoundary.jsx +54 -0
- package/src/dashboard/app/components/FlowGraph.jsx +19 -17
- package/src/dashboard/app/components/KnowledgeMarkdown.jsx +53 -0
- package/src/dashboard/app/components/Markdown.jsx +47 -0
- package/src/dashboard/app/components/PhaseRail.jsx +111 -0
- package/src/dashboard/app/components/SearchFilter.jsx +40 -22
- package/src/dashboard/app/components/Sidebar.jsx +146 -37
- package/src/dashboard/app/hooks/useMorphQuery.js +54 -0
- package/src/dashboard/app/hooks/usePref.js +38 -0
- package/src/dashboard/app/lib/format.js +69 -0
- package/src/dashboard/app/lib/phases.js +56 -0
- package/src/dashboard/app/lib/project.js +50 -0
- package/src/dashboard/app/pages/Activity.jsx +24 -0
- package/src/dashboard/app/pages/AgentMap.jsx +371 -370
- package/src/dashboard/app/pages/FeatureDetail.jsx +604 -0
- package/src/dashboard/app/pages/Features.jsx +400 -0
- package/src/dashboard/app/pages/Guide.jsx +146 -0
- package/src/dashboard/app/pages/HookInspector.jsx +357 -322
- package/src/dashboard/app/pages/PhasePipeline.jsx +277 -408
- package/src/dashboard/app/pages/Portfolio.jsx +156 -0
- package/src/dashboard/app/pages/Rubrics.jsx +101 -0
- package/src/dashboard/app/pages/RulesMap.jsx +300 -273
- package/src/dashboard/app/pages/SkillsLibrary.jsx +483 -366
- package/src/dashboard/app/pages/Standards.jsx +407 -332
- package/src/dashboard/app/styles/index.css +187 -47
- package/src/dashboard/index.html +14 -12
- package/src/dashboard/package.json +32 -24
- package/src/dashboard/scanner/activity-scanner.js +351 -0
- package/src/dashboard/scanner/agents-scanner.js +59 -1
- package/src/dashboard/scanner/docs-scanner.js +59 -0
- package/src/dashboard/scanner/feature-status.js +10 -0
- package/src/dashboard/scanner/features-scanner.js +360 -0
- package/src/dashboard/scanner/index.js +14 -7
- package/src/dashboard/scanner/phases-scanner.js +14 -15
- package/src/dashboard/scanner/portfolio.js +153 -0
- package/src/dashboard/scanner/project-api.js +195 -0
- package/src/dashboard/scanner/rules-scanner.js +42 -37
- package/src/dashboard/scanner/skills-scanner.js +105 -43
- package/src/dashboard/scanner/standards-scanner.js +2 -0
- package/src/dashboard/vite-plugin-morph-data.js +134 -17
- package/src/lib/detectors/claude-config-detector.js +2 -7
- package/src/lib/detectors/index.js +5 -1
- package/src/lib/evaluator-report.js +22 -0
- package/src/lib/generators/settings-generator.js +208 -209
- package/src/lib/installers/mcp-installer.js +724 -719
- package/src/lib/installers/memory-installer.js +1 -2
- package/src/lib/projects/registry.js +154 -0
- package/src/lib/risk-detector.js +13 -0
- package/src/lib/tasks/tasks-json-parser.js +21 -0
- package/src/lib/validators/code-budget/code-budget-validator.js +32 -4
- package/src/lib/worktree/env-allocator.js +9 -3
- package/src/scripts/install-plugin.js +1 -1
- package/src/scripts/setup-infra.js +2 -4
- package/src/utils/agents-installer.js +108 -13
- package/src/utils/banner.js +1 -1
- package/src/commands/index.js +0 -13
- package/src/commands/project/checkpoint.js +0 -209
- package/src/core/state/phase-state-machine.js +0 -197
- package/src/dashboard/app/hooks/useDetailPanel.js +0 -15
- package/src/dashboard/app/pages/LiveState.jsx +0 -206
- package/src/dashboard/scanner/squads-scanner.js +0 -13
- package/src/dashboard/scanner/state-scanner.js +0 -85
- package/src/lib/generators/index.js +0 -10
- package/src/lib/hooks/hook-executor.js +0 -167
- package/src/lib/validators/checkpoint-persistence.js +0 -39
- package/src/lib/validators/shared/emit-validator-dispatch.js +0 -14
- package/src/lib/validators/shared/index.js +0 -12
- package/src/lib/validators/shared/issue-counter.js +0 -14
- package/src/lib/validators/shared/result-formatter.js +0 -124
|
@@ -1,8 +1,3 @@
|
|
|
1
|
-
// ============================================================
|
|
2
|
-
// TEST TEMPLATE (VSA Pattern — Handler + Validator)
|
|
3
|
-
// Generated by MORPH Framework
|
|
4
|
-
// ============================================================
|
|
5
|
-
|
|
6
1
|
using FluentAssertions;
|
|
7
2
|
using FluentValidation;
|
|
8
3
|
using FluentValidation.Results;
|
|
@@ -14,15 +9,6 @@ using Xunit;
|
|
|
14
9
|
|
|
15
10
|
namespace {{pascalCase PROJECT_NAME}}.Tests.Unit.Features.{{pascalCase FEATURE_NAME}};
|
|
16
11
|
|
|
17
|
-
// ============================================================
|
|
18
|
-
// Handler Tests
|
|
19
|
-
// ============================================================
|
|
20
|
-
|
|
21
|
-
/// <summary>
|
|
22
|
-
/// Unit tests for {{pascalCase FEATURE_NAME}} handlers.
|
|
23
|
-
/// Tests handlers directly against a real ApplicationDbContext backed by
|
|
24
|
-
/// in-memory SQLite (no mocks — DbSet is the repository, DbContext is the unit of work).
|
|
25
|
-
/// </summary>
|
|
26
12
|
public class {{pascalCase FEATURE_NAME}}HandlerTests : IDisposable
|
|
27
13
|
{
|
|
28
14
|
private readonly SqliteConnection _connection;
|
|
@@ -30,6 +16,7 @@ public class {{pascalCase FEATURE_NAME}}HandlerTests : IDisposable
|
|
|
30
16
|
|
|
31
17
|
public {{pascalCase FEATURE_NAME}}HandlerTests()
|
|
32
18
|
{
|
|
19
|
+
// o banco :memory: some quando a conexão fecha, então ela vive o teste inteiro
|
|
33
20
|
_connection = new SqliteConnection("DataSource=:memory:");
|
|
34
21
|
_connection.Open();
|
|
35
22
|
|
|
@@ -47,19 +34,14 @@ public class {{pascalCase FEATURE_NAME}}HandlerTests : IDisposable
|
|
|
47
34
|
_connection.Dispose();
|
|
48
35
|
}
|
|
49
36
|
|
|
50
|
-
#region Create Handler Tests
|
|
51
|
-
|
|
52
37
|
[Fact]
|
|
53
38
|
public async Task Create_HandleAsync_WithValidCommand_ReturnsSuccessResult()
|
|
54
39
|
{
|
|
55
|
-
// Arrange
|
|
56
40
|
var command = new Create{{pascalCase FEATURE_NAME}}Request("Test {{pascalCase FEATURE_NAME}}");
|
|
57
41
|
var handler = new Create{{pascalCase FEATURE_NAME}}Handler(_db);
|
|
58
42
|
|
|
59
|
-
// Act
|
|
60
43
|
var result = await handler.HandleAsync(command, CancellationToken.None);
|
|
61
44
|
|
|
62
|
-
// Assert
|
|
63
45
|
result.IsSuccess.Should().BeTrue();
|
|
64
46
|
result.Value.Should().NotBeNull();
|
|
65
47
|
|
|
@@ -67,14 +49,9 @@ public class {{pascalCase FEATURE_NAME}}HandlerTests : IDisposable
|
|
|
67
49
|
persisted.Name.Should().Be("Test {{pascalCase FEATURE_NAME}}");
|
|
68
50
|
}
|
|
69
51
|
|
|
70
|
-
#endregion
|
|
71
|
-
|
|
72
|
-
#region GetById Handler Tests
|
|
73
|
-
|
|
74
52
|
[Fact]
|
|
75
53
|
public async Task GetById_HandleAsync_WithValidId_ReturnsSuccessResult()
|
|
76
54
|
{
|
|
77
|
-
// Arrange
|
|
78
55
|
var entity = CreateTestEntity("Test {{pascalCase FEATURE_NAME}}");
|
|
79
56
|
_db.Set<{{pascalCase FEATURE_NAME}}>().Add(entity);
|
|
80
57
|
await _db.SaveChangesAsync();
|
|
@@ -82,10 +59,8 @@ public class {{pascalCase FEATURE_NAME}}HandlerTests : IDisposable
|
|
|
82
59
|
var query = new Get{{pascalCase FEATURE_NAME}}ByIdRequest(entity.Id);
|
|
83
60
|
var handler = new Get{{pascalCase FEATURE_NAME}}ByIdHandler(_db);
|
|
84
61
|
|
|
85
|
-
// Act
|
|
86
62
|
var result = await handler.HandleAsync(query, CancellationToken.None);
|
|
87
63
|
|
|
88
|
-
// Assert
|
|
89
64
|
result.IsSuccess.Should().BeTrue();
|
|
90
65
|
result.Value.Should().NotBeNull();
|
|
91
66
|
result.Value!.Name.Should().Be("Test {{pascalCase FEATURE_NAME}}");
|
|
@@ -94,25 +69,17 @@ public class {{pascalCase FEATURE_NAME}}HandlerTests : IDisposable
|
|
|
94
69
|
[Fact]
|
|
95
70
|
public async Task GetById_HandleAsync_WithInvalidId_ReturnsFailureResult()
|
|
96
71
|
{
|
|
97
|
-
// Arrange
|
|
98
72
|
var query = new Get{{pascalCase FEATURE_NAME}}ByIdRequest(Guid.CreateVersion7());
|
|
99
73
|
var handler = new Get{{pascalCase FEATURE_NAME}}ByIdHandler(_db);
|
|
100
74
|
|
|
101
|
-
// Act
|
|
102
75
|
var result = await handler.HandleAsync(query, CancellationToken.None);
|
|
103
76
|
|
|
104
|
-
// Assert
|
|
105
77
|
result.IsSuccess.Should().BeFalse();
|
|
106
78
|
}
|
|
107
79
|
|
|
108
|
-
#endregion
|
|
109
|
-
|
|
110
|
-
#region Update Handler Tests
|
|
111
|
-
|
|
112
80
|
[Fact]
|
|
113
81
|
public async Task Update_HandleAsync_WithValidCommand_ReturnsSuccessResult()
|
|
114
82
|
{
|
|
115
|
-
// Arrange
|
|
116
83
|
var entity = CreateTestEntity("Original Name");
|
|
117
84
|
_db.Set<{{pascalCase FEATURE_NAME}}>().Add(entity);
|
|
118
85
|
await _db.SaveChangesAsync();
|
|
@@ -120,10 +87,8 @@ public class {{pascalCase FEATURE_NAME}}HandlerTests : IDisposable
|
|
|
120
87
|
var command = new Update{{pascalCase FEATURE_NAME}}Request(entity.Id, "Updated Name");
|
|
121
88
|
var handler = new Update{{pascalCase FEATURE_NAME}}Handler(_db);
|
|
122
89
|
|
|
123
|
-
// Act
|
|
124
90
|
var result = await handler.HandleAsync(command, CancellationToken.None);
|
|
125
91
|
|
|
126
|
-
// Assert
|
|
127
92
|
result.IsSuccess.Should().BeTrue();
|
|
128
93
|
|
|
129
94
|
var persisted = await _db.Set<{{pascalCase FEATURE_NAME}}>().SingleAsync(x => x.Id == entity.Id);
|
|
@@ -133,25 +98,17 @@ public class {{pascalCase FEATURE_NAME}}HandlerTests : IDisposable
|
|
|
133
98
|
[Fact]
|
|
134
99
|
public async Task Update_HandleAsync_WithNonExistentId_ReturnsFailureResult()
|
|
135
100
|
{
|
|
136
|
-
// Arrange
|
|
137
101
|
var command = new Update{{pascalCase FEATURE_NAME}}Request(Guid.CreateVersion7(), "Updated");
|
|
138
102
|
var handler = new Update{{pascalCase FEATURE_NAME}}Handler(_db);
|
|
139
103
|
|
|
140
|
-
// Act
|
|
141
104
|
var result = await handler.HandleAsync(command, CancellationToken.None);
|
|
142
105
|
|
|
143
|
-
// Assert
|
|
144
106
|
result.IsSuccess.Should().BeFalse();
|
|
145
107
|
}
|
|
146
108
|
|
|
147
|
-
#endregion
|
|
148
|
-
|
|
149
|
-
#region Delete Handler Tests
|
|
150
|
-
|
|
151
109
|
[Fact]
|
|
152
110
|
public async Task Delete_HandleAsync_WithValidId_ReturnsSuccessResult()
|
|
153
111
|
{
|
|
154
|
-
// Arrange
|
|
155
112
|
var entity = CreateTestEntity("To Delete");
|
|
156
113
|
_db.Set<{{pascalCase FEATURE_NAME}}>().Add(entity);
|
|
157
114
|
await _db.SaveChangesAsync();
|
|
@@ -159,10 +116,8 @@ public class {{pascalCase FEATURE_NAME}}HandlerTests : IDisposable
|
|
|
159
116
|
var command = new Delete{{pascalCase FEATURE_NAME}}Request(entity.Id);
|
|
160
117
|
var handler = new Delete{{pascalCase FEATURE_NAME}}Handler(_db);
|
|
161
118
|
|
|
162
|
-
// Act
|
|
163
119
|
var result = await handler.HandleAsync(command, CancellationToken.None);
|
|
164
120
|
|
|
165
|
-
// Assert
|
|
166
121
|
result.IsSuccess.Should().BeTrue();
|
|
167
122
|
|
|
168
123
|
(await _db.Set<{{pascalCase FEATURE_NAME}}>().AnyAsync(x => x.Id == entity.Id)).Should().BeFalse();
|
|
@@ -171,57 +126,35 @@ public class {{pascalCase FEATURE_NAME}}HandlerTests : IDisposable
|
|
|
171
126
|
[Fact]
|
|
172
127
|
public async Task Delete_HandleAsync_WithNonExistentId_ReturnsFailureResult()
|
|
173
128
|
{
|
|
174
|
-
// Arrange
|
|
175
129
|
var command = new Delete{{pascalCase FEATURE_NAME}}Request(Guid.CreateVersion7());
|
|
176
130
|
var handler = new Delete{{pascalCase FEATURE_NAME}}Handler(_db);
|
|
177
131
|
|
|
178
|
-
// Act
|
|
179
132
|
var result = await handler.HandleAsync(command, CancellationToken.None);
|
|
180
133
|
|
|
181
|
-
// Assert
|
|
182
134
|
result.IsSuccess.Should().BeFalse();
|
|
183
135
|
}
|
|
184
136
|
|
|
185
|
-
#endregion
|
|
186
|
-
|
|
187
|
-
#region Helper Methods
|
|
188
|
-
|
|
189
137
|
private static {{pascalCase FEATURE_NAME}} CreateTestEntity(string name)
|
|
190
138
|
{
|
|
191
139
|
return new {{pascalCase FEATURE_NAME}}
|
|
192
140
|
{
|
|
193
141
|
Id = Guid.CreateVersion7(),
|
|
194
142
|
Name = name,
|
|
195
|
-
// TODO:
|
|
143
|
+
// TODO: demais campos obrigatórios da entidade
|
|
196
144
|
};
|
|
197
145
|
}
|
|
198
|
-
|
|
199
|
-
#endregion
|
|
200
146
|
}
|
|
201
147
|
|
|
202
|
-
// ============================================================
|
|
203
|
-
// Validator Tests
|
|
204
|
-
// ============================================================
|
|
205
|
-
|
|
206
|
-
/// <summary>
|
|
207
|
-
/// Unit tests for {{pascalCase FEATURE_NAME}} validators.
|
|
208
|
-
/// Tests FluentValidation rules using ValidateAsync.
|
|
209
|
-
/// </summary>
|
|
210
148
|
public class {{pascalCase FEATURE_NAME}}ValidatorTests
|
|
211
149
|
{
|
|
212
|
-
#region Create Validator Tests
|
|
213
|
-
|
|
214
150
|
[Fact]
|
|
215
151
|
public async Task CreateValidator_WithValidCommand_PassesValidation()
|
|
216
152
|
{
|
|
217
|
-
// Arrange
|
|
218
153
|
var validator = new Create{{pascalCase FEATURE_NAME}}Validator();
|
|
219
154
|
var command = new Create{{pascalCase FEATURE_NAME}}Request("Valid Name");
|
|
220
155
|
|
|
221
|
-
// Act
|
|
222
156
|
ValidationResult result = await validator.ValidateAsync(command);
|
|
223
157
|
|
|
224
|
-
// Assert
|
|
225
158
|
result.IsValid.Should().BeTrue();
|
|
226
159
|
result.Errors.Should().BeEmpty();
|
|
227
160
|
}
|
|
@@ -232,14 +165,11 @@ public class {{pascalCase FEATURE_NAME}}ValidatorTests
|
|
|
232
165
|
[InlineData(null)]
|
|
233
166
|
public async Task CreateValidator_WithInvalidName_FailsValidation(string? name)
|
|
234
167
|
{
|
|
235
|
-
// Arrange
|
|
236
168
|
var validator = new Create{{pascalCase FEATURE_NAME}}Validator();
|
|
237
169
|
var command = new Create{{pascalCase FEATURE_NAME}}Request(name!);
|
|
238
170
|
|
|
239
|
-
// Act
|
|
240
171
|
ValidationResult result = await validator.ValidateAsync(command);
|
|
241
172
|
|
|
242
|
-
// Assert
|
|
243
173
|
result.IsValid.Should().BeFalse();
|
|
244
174
|
result.Errors.Should().Contain(e => e.PropertyName == nameof(Create{{pascalCase FEATURE_NAME}}Request.Name));
|
|
245
175
|
}
|
|
@@ -247,50 +177,35 @@ public class {{pascalCase FEATURE_NAME}}ValidatorTests
|
|
|
247
177
|
[Fact]
|
|
248
178
|
public async Task CreateValidator_WithNameExceedingMaxLength_FailsValidation()
|
|
249
179
|
{
|
|
250
|
-
// Arrange
|
|
251
180
|
var validator = new Create{{pascalCase FEATURE_NAME}}Validator();
|
|
252
181
|
var command = new Create{{pascalCase FEATURE_NAME}}Request(new string('A', 201));
|
|
253
182
|
|
|
254
|
-
// Act
|
|
255
183
|
ValidationResult result = await validator.ValidateAsync(command);
|
|
256
184
|
|
|
257
|
-
// Assert
|
|
258
185
|
result.IsValid.Should().BeFalse();
|
|
259
186
|
result.Errors.Should().Contain(e => e.PropertyName == nameof(Create{{pascalCase FEATURE_NAME}}Request.Name));
|
|
260
187
|
}
|
|
261
188
|
|
|
262
|
-
#endregion
|
|
263
|
-
|
|
264
|
-
#region Update Validator Tests
|
|
265
|
-
|
|
266
189
|
[Fact]
|
|
267
190
|
public async Task UpdateValidator_WithValidCommand_PassesValidation()
|
|
268
191
|
{
|
|
269
|
-
// Arrange
|
|
270
192
|
var validator = new Update{{pascalCase FEATURE_NAME}}Validator();
|
|
271
193
|
var command = new Update{{pascalCase FEATURE_NAME}}Request(Guid.CreateVersion7(), "Updated Name");
|
|
272
194
|
|
|
273
|
-
// Act
|
|
274
195
|
ValidationResult result = await validator.ValidateAsync(command);
|
|
275
196
|
|
|
276
|
-
// Assert
|
|
277
197
|
result.IsValid.Should().BeTrue();
|
|
278
198
|
}
|
|
279
199
|
|
|
280
200
|
[Fact]
|
|
281
201
|
public async Task UpdateValidator_WithInvalidId_FailsValidation()
|
|
282
202
|
{
|
|
283
|
-
// Arrange
|
|
284
203
|
var validator = new Update{{pascalCase FEATURE_NAME}}Validator();
|
|
285
204
|
var command = new Update{{pascalCase FEATURE_NAME}}Request(Guid.Empty, "Updated Name");
|
|
286
205
|
|
|
287
|
-
// Act
|
|
288
206
|
ValidationResult result = await validator.ValidateAsync(command);
|
|
289
207
|
|
|
290
|
-
// Assert
|
|
291
208
|
result.IsValid.Should().BeFalse();
|
|
292
209
|
result.Errors.Should().Contain(e => e.PropertyName == nameof(Update{{pascalCase FEATURE_NAME}}Request.Id));
|
|
293
210
|
}
|
|
294
|
-
|
|
295
|
-
#endregion
|
|
296
211
|
}
|
|
@@ -1,167 +1,140 @@
|
|
|
1
|
-
//
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
};
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
export
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
export interface
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
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
|
-
|
|
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
|
}
|