sofia-cli 0.1.1
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/.github/agents/copilot-instructions.md +39 -0
- package/.github/agents/speckit.analyze.agent.md +184 -0
- package/.github/agents/speckit.checklist.agent.md +294 -0
- package/.github/agents/speckit.clarify.agent.md +181 -0
- package/.github/agents/speckit.constitution.agent.md +84 -0
- package/.github/agents/speckit.implement.agent.md +135 -0
- package/.github/agents/speckit.plan.agent.md +90 -0
- package/.github/agents/speckit.specify.agent.md +258 -0
- package/.github/agents/speckit.tasks.agent.md +137 -0
- package/.github/agents/speckit.taskstoissues.agent.md +30 -0
- package/.github/copilot-instructions.md +257 -0
- package/.github/prompts/speckit.analyze.prompt.md +3 -0
- package/.github/prompts/speckit.checklist.prompt.md +3 -0
- package/.github/prompts/speckit.clarify.prompt.md +3 -0
- package/.github/prompts/speckit.constitution.prompt.md +3 -0
- package/.github/prompts/speckit.implement.prompt.md +3 -0
- package/.github/prompts/speckit.plan.prompt.md +3 -0
- package/.github/prompts/speckit.specify.prompt.md +3 -0
- package/.github/prompts/speckit.tasks.prompt.md +3 -0
- package/.github/prompts/speckit.taskstoissues.prompt.md +3 -0
- package/.github/workflows/ci.yml +38 -0
- package/.prettierrc +6 -0
- package/.specify/memory/constitution.md +181 -0
- package/.specify/scripts/bash/check-prerequisites.sh +166 -0
- package/.specify/scripts/bash/common.sh +156 -0
- package/.specify/scripts/bash/create-new-feature.sh +297 -0
- package/.specify/scripts/bash/setup-plan.sh +61 -0
- package/.specify/scripts/bash/update-agent-context.sh +810 -0
- package/.specify/templates/agent-file-template.md +28 -0
- package/.specify/templates/checklist-template.md +40 -0
- package/.specify/templates/constitution-template.md +50 -0
- package/.specify/templates/plan-template.md +113 -0
- package/.specify/templates/spec-template.md +115 -0
- package/.specify/templates/tasks-template.md +251 -0
- package/.vscode/mcp.json +42 -0
- package/.vscode/settings.json +19 -0
- package/CODE_OF_CONDUCT.md +128 -0
- package/LICENSE +21 -0
- package/README.md +213 -0
- package/dist/src/cli/developCommand.js +240 -0
- package/dist/src/cli/directCommands.js +143 -0
- package/dist/src/cli/envLoader.js +16 -0
- package/dist/src/cli/exportCommand.js +53 -0
- package/dist/src/cli/index.js +203 -0
- package/dist/src/cli/ioContext.js +109 -0
- package/dist/src/cli/preflight.js +57 -0
- package/dist/src/cli/statusCommand.js +110 -0
- package/dist/src/cli/workshopCommand.js +400 -0
- package/dist/src/develop/checkpointState.js +86 -0
- package/dist/src/develop/codeGenerator.js +319 -0
- package/dist/src/develop/dynamicScaffolder.js +226 -0
- package/dist/src/develop/githubMcpAdapter.js +122 -0
- package/dist/src/develop/index.js +15 -0
- package/dist/src/develop/mcpContextEnricher.js +195 -0
- package/dist/src/develop/pocScaffolder.js +542 -0
- package/dist/src/develop/ralphLoop.js +659 -0
- package/dist/src/develop/templateRegistry.js +364 -0
- package/dist/src/develop/testRunner.js +202 -0
- package/dist/src/logging/logger.js +58 -0
- package/dist/src/loop/conversationLoop.js +227 -0
- package/dist/src/loop/phaseSummarizer.js +87 -0
- package/dist/src/mcp/mcpManager.js +267 -0
- package/dist/src/mcp/mcpTransport.js +391 -0
- package/dist/src/mcp/retryPolicy.js +47 -0
- package/dist/src/mcp/webSearch.js +254 -0
- package/dist/src/phases/contextSummarizer.js +101 -0
- package/dist/src/phases/discoveryEnricher.js +156 -0
- package/dist/src/phases/phaseExtractors.js +222 -0
- package/dist/src/phases/phaseHandlers.js +328 -0
- package/dist/src/prompts/design.md +51 -0
- package/dist/src/prompts/develop-boundary.md +51 -0
- package/dist/src/prompts/develop.md +111 -0
- package/dist/src/prompts/discover.md +58 -0
- package/dist/src/prompts/ideate.md +56 -0
- package/dist/src/prompts/plan.md +51 -0
- package/dist/src/prompts/promptLoader.js +167 -0
- package/dist/src/prompts/promptLoader.ts +198 -0
- package/dist/src/prompts/select.md +47 -0
- package/dist/src/prompts/summarize/README.md +8 -0
- package/dist/src/prompts/summarize/design-summary.md +37 -0
- package/dist/src/prompts/summarize/develop-summary.md +25 -0
- package/dist/src/prompts/summarize/ideate-summary.md +27 -0
- package/dist/src/prompts/summarize/plan-summary.md +27 -0
- package/dist/src/prompts/summarize/select-summary.md +21 -0
- package/dist/src/prompts/system.md +28 -0
- package/dist/src/sessions/exportPaths.js +22 -0
- package/dist/src/sessions/exportWriter.js +406 -0
- package/dist/src/sessions/sessionManager.js +81 -0
- package/dist/src/sessions/sessionStore.js +65 -0
- package/dist/src/shared/activitySpinner.js +91 -0
- package/dist/src/shared/copilotClient.js +129 -0
- package/dist/src/shared/data/cards.json +1249 -0
- package/dist/src/shared/data/cardsLoader.js +51 -0
- package/dist/src/shared/errorClassifier.js +120 -0
- package/dist/src/shared/events.js +28 -0
- package/dist/src/shared/markdownRenderer.js +34 -0
- package/dist/src/shared/schemas/session.js +265 -0
- package/dist/src/shared/tableRenderer.js +20 -0
- package/dist/src/vendor/chalk.js +2 -0
- package/dist/src/vendor/cli-table3.js +3 -0
- package/dist/src/vendor/commander.js +2 -0
- package/dist/src/vendor/marked-terminal.js +3 -0
- package/dist/src/vendor/marked.js +2 -0
- package/dist/src/vendor/ora.js +2 -0
- package/dist/src/vendor/pino.js +2 -0
- package/dist/src/vendor/zod.js +2 -0
- package/dist/tests/e2e/developE2e.spec.js +126 -0
- package/dist/tests/e2e/developFailureE2e.spec.js +247 -0
- package/dist/tests/e2e/developPty.spec.js +75 -0
- package/dist/tests/e2e/discoveryWebSearchRelevance.spec.js +84 -0
- package/dist/tests/e2e/harness.spec.js +83 -0
- package/dist/tests/e2e/mcpLive.spec.js +120 -0
- package/dist/tests/e2e/newSession.e2e.spec.js +177 -0
- package/dist/tests/e2e/ralphLoopEnrichmentComparison.spec.js +62 -0
- package/dist/tests/e2e/workiqEnrichment.spec.js +56 -0
- package/dist/tests/e2e/zavaSimulation.spec.js +452 -0
- package/dist/tests/fixtures/test-fixture-project/src/add.js +3 -0
- package/dist/tests/fixtures/test-fixture-project/tests/failing.test.js +6 -0
- package/dist/tests/fixtures/test-fixture-project/tests/hanging.test.js +8 -0
- package/dist/tests/fixtures/test-fixture-project/tests/passing.test.js +10 -0
- package/dist/tests/fixtures/test-fixture-project/vitest.config.js +6 -0
- package/dist/tests/integration/autoStartConversation.spec.js +138 -0
- package/dist/tests/integration/defaultCommand.spec.js +147 -0
- package/dist/tests/integration/directCommandNonTty.spec.js +224 -0
- package/dist/tests/integration/directCommandTty.spec.js +151 -0
- package/dist/tests/integration/discoveryEnrichmentFlow.spec.js +175 -0
- package/dist/tests/integration/exportArtifacts.spec.js +202 -0
- package/dist/tests/integration/exportFallbackFlow.spec.js +99 -0
- package/dist/tests/integration/mcpDegradationFlow.spec.js +190 -0
- package/dist/tests/integration/mcpTransportFlow.spec.js +139 -0
- package/dist/tests/integration/newSessionFlow.spec.js +343 -0
- package/dist/tests/integration/pocGithubMcp.spec.js +186 -0
- package/dist/tests/integration/pocLocalFallback.spec.js +171 -0
- package/dist/tests/integration/pocScaffold.spec.js +163 -0
- package/dist/tests/integration/ralphLoopFlow.spec.js +359 -0
- package/dist/tests/integration/ralphLoopPartial.spec.js +368 -0
- package/dist/tests/integration/resumeAndBacktrack.spec.js +247 -0
- package/dist/tests/integration/spinnerLifecycle.spec.js +220 -0
- package/dist/tests/integration/summarizationFlow.spec.js +115 -0
- package/dist/tests/integration/testRunnerReal.spec.js +52 -0
- package/dist/tests/integration/webSearchAgent.spec.js +128 -0
- package/dist/tests/live/copilotSdkLive.spec.js +107 -0
- package/dist/tests/live/zavaFullWorkshop.spec.js +392 -0
- package/dist/tests/setup/loadEnv.js +3 -0
- package/dist/tests/unit/cli/developCommand.spec.js +567 -0
- package/dist/tests/unit/cli/directCommands.spec.js +279 -0
- package/dist/tests/unit/cli/envLoader.spec.js +58 -0
- package/dist/tests/unit/cli/ioContext.spec.js +119 -0
- package/dist/tests/unit/cli/preflight.spec.js +108 -0
- package/dist/tests/unit/cli/statusCommand.spec.js +111 -0
- package/dist/tests/unit/cli/workshopClientFallback.spec.js +80 -0
- package/dist/tests/unit/cli/workshopCommand.spec.js +329 -0
- package/dist/tests/unit/config/vitestEnvSetup.spec.js +13 -0
- package/dist/tests/unit/develop/checkpointState.spec.js +315 -0
- package/dist/tests/unit/develop/codeGenerator.spec.js +355 -0
- package/dist/tests/unit/develop/githubMcpAdapter.spec.js +231 -0
- package/dist/tests/unit/develop/mcpContextEnricher.spec.js +433 -0
- package/dist/tests/unit/develop/outputValidator.spec.js +119 -0
- package/dist/tests/unit/develop/pocScaffolder.spec.js +353 -0
- package/dist/tests/unit/develop/ralphLoop.spec.js +1248 -0
- package/dist/tests/unit/develop/templateRegistry.spec.js +85 -0
- package/dist/tests/unit/develop/testRunner.spec.js +249 -0
- package/dist/tests/unit/infraBicep.spec.js +92 -0
- package/dist/tests/unit/infraDeploy.spec.js +82 -0
- package/dist/tests/unit/infraTeardown.spec.js +63 -0
- package/dist/tests/unit/logging/logger.spec.js +43 -0
- package/dist/tests/unit/loop/conversationLoop.spec.js +592 -0
- package/dist/tests/unit/loop/phaseSummarizer.spec.js +141 -0
- package/dist/tests/unit/loop/streamingMarkdown.spec.js +147 -0
- package/dist/tests/unit/mcp/mcpManager.spec.js +279 -0
- package/dist/tests/unit/mcp/mcpTransport.spec.js +529 -0
- package/dist/tests/unit/mcp/retryPolicy.spec.js +218 -0
- package/dist/tests/unit/mcp/timeoutValidation.spec.js +46 -0
- package/dist/tests/unit/mcp/webSearch.spec.js +567 -0
- package/dist/tests/unit/phases/contextSummarizer.spec.js +140 -0
- package/dist/tests/unit/phases/discoveryEnricher.repeatCalls.spec.js +93 -0
- package/dist/tests/unit/phases/discoveryEnricher.spec.js +411 -0
- package/dist/tests/unit/phases/phaseExtractors.spec.js +352 -0
- package/dist/tests/unit/phases/phaseHandlers.spec.js +425 -0
- package/dist/tests/unit/prompts/promptLoader.spec.js +118 -0
- package/dist/tests/unit/schemas/pocSchemas.spec.js +412 -0
- package/dist/tests/unit/schemas/session.spec.js +257 -0
- package/dist/tests/unit/sessions/exportPaths.spec.js +31 -0
- package/dist/tests/unit/sessions/exportWriter.spec.js +655 -0
- package/dist/tests/unit/sessions/sessionManager.spec.js +151 -0
- package/dist/tests/unit/sessions/sessionStore.spec.js +116 -0
- package/dist/tests/unit/shared/activitySpinner.spec.js +175 -0
- package/dist/tests/unit/shared/cardsLoader.spec.js +76 -0
- package/dist/tests/unit/shared/copilotClient.spec.js +155 -0
- package/dist/tests/unit/shared/errorClassifier.spec.js +131 -0
- package/dist/tests/unit/shared/events.spec.js +55 -0
- package/dist/tests/unit/shared/markdownRenderer.spec.js +35 -0
- package/dist/tests/unit/shared/markdownRendererChunks.spec.js +70 -0
- package/dist/tests/unit/shared/tableRenderer.spec.js +34 -0
- package/dist/vitest.config.js +14 -0
- package/dist/vitest.live.config.js +18 -0
- package/docs/README.md +35 -0
- package/docs/architecture.md +169 -0
- package/docs/cli-usage.md +207 -0
- package/docs/environment.md +66 -0
- package/docs/export-format.md +146 -0
- package/docs/session-model.md +113 -0
- package/eslint.config.js +35 -0
- package/infra/deploy.sh +193 -0
- package/infra/gather-env.sh +211 -0
- package/infra/main.bicep +90 -0
- package/infra/main.bicepparam +18 -0
- package/infra/resources.bicep +134 -0
- package/infra/teardown.sh +114 -0
- package/package.json +63 -0
- package/specs/001-cli-workshop-rebuild/checklists/requirements.md +35 -0
- package/specs/001-cli-workshop-rebuild/contracts/cli.md +59 -0
- package/specs/001-cli-workshop-rebuild/contracts/export-summary-json.md +23 -0
- package/specs/001-cli-workshop-rebuild/contracts/session-json.md +30 -0
- package/specs/001-cli-workshop-rebuild/data-model.md +210 -0
- package/specs/001-cli-workshop-rebuild/plan.md +361 -0
- package/specs/001-cli-workshop-rebuild/quickstart.md +83 -0
- package/specs/001-cli-workshop-rebuild/research.md +116 -0
- package/specs/001-cli-workshop-rebuild/spec.md +240 -0
- package/specs/001-cli-workshop-rebuild/tasks.md +476 -0
- package/specs/002-poc-generation/contracts/poc-output.md +172 -0
- package/specs/002-poc-generation/contracts/ralph-loop.md +113 -0
- package/specs/002-poc-generation/data-model.md +172 -0
- package/specs/002-poc-generation/plan.md +109 -0
- package/specs/002-poc-generation/quickstart.md +97 -0
- package/specs/002-poc-generation/research.md +786 -0
- package/specs/002-poc-generation/spec.md +81 -0
- package/specs/002-poc-generation/tasks-fix.md +198 -0
- package/specs/002-poc-generation/tasks.md +252 -0
- package/specs/003-mcp-transport-integration/checklists/requirements.md +37 -0
- package/specs/003-mcp-transport-integration/contracts/context-enricher.md +220 -0
- package/specs/003-mcp-transport-integration/contracts/discovery-enricher.md +267 -0
- package/specs/003-mcp-transport-integration/contracts/github-adapter.md +149 -0
- package/specs/003-mcp-transport-integration/contracts/mcp-transport.md +288 -0
- package/specs/003-mcp-transport-integration/data-model.md +326 -0
- package/specs/003-mcp-transport-integration/plan.md +114 -0
- package/specs/003-mcp-transport-integration/quickstart.md +311 -0
- package/specs/003-mcp-transport-integration/research.md +395 -0
- package/specs/003-mcp-transport-integration/spec.md +234 -0
- package/specs/003-mcp-transport-integration/tasks.md +324 -0
- package/specs/003-next-spec-gaps.md +150 -0
- package/specs/004-dev-resume-hardening/checklists/requirements.md +37 -0
- package/specs/004-dev-resume-hardening/contracts/cli.md +160 -0
- package/specs/004-dev-resume-hardening/data-model.md +321 -0
- package/specs/004-dev-resume-hardening/plan.md +107 -0
- package/specs/004-dev-resume-hardening/quickstart.md +115 -0
- package/specs/004-dev-resume-hardening/research.md +142 -0
- package/specs/004-dev-resume-hardening/spec.md +221 -0
- package/specs/004-dev-resume-hardening/tasks.md +333 -0
- package/specs/005-ai-search-deploy/checklists/requirements.md +39 -0
- package/specs/005-ai-search-deploy/contracts/web-search-tool.md +241 -0
- package/specs/005-ai-search-deploy/data-model.md +130 -0
- package/specs/005-ai-search-deploy/plan.md +93 -0
- package/specs/005-ai-search-deploy/quickstart.md +96 -0
- package/specs/005-ai-search-deploy/research.md +187 -0
- package/specs/005-ai-search-deploy/spec.md +143 -0
- package/specs/005-ai-search-deploy/tasks.md +284 -0
- package/specs/006-workshop-extraction-fixes/checklists/requirements.md +61 -0
- package/specs/006-workshop-extraction-fixes/contracts/summarization-and-export.md +131 -0
- package/specs/006-workshop-extraction-fixes/data-model.md +149 -0
- package/specs/006-workshop-extraction-fixes/plan.md +123 -0
- package/specs/006-workshop-extraction-fixes/quickstart.md +101 -0
- package/specs/006-workshop-extraction-fixes/research.md +143 -0
- package/specs/006-workshop-extraction-fixes/spec.md +210 -0
- package/specs/006-workshop-extraction-fixes/tasks.md +316 -0
- package/src/cli/developCommand.ts +308 -0
- package/src/cli/directCommands.ts +195 -0
- package/src/cli/envLoader.ts +17 -0
- package/src/cli/exportCommand.ts +65 -0
- package/src/cli/index.ts +249 -0
- package/src/cli/ioContext.ts +139 -0
- package/src/cli/preflight.ts +86 -0
- package/src/cli/statusCommand.ts +118 -0
- package/src/cli/workshopCommand.ts +496 -0
- package/src/develop/checkpointState.ts +121 -0
- package/src/develop/codeGenerator.ts +402 -0
- package/src/develop/dynamicScaffolder.ts +284 -0
- package/src/develop/githubMcpAdapter.ts +199 -0
- package/src/develop/index.ts +34 -0
- package/src/develop/mcpContextEnricher.ts +279 -0
- package/src/develop/pocScaffolder.ts +646 -0
- package/src/develop/ralphLoop.ts +1044 -0
- package/src/develop/templateRegistry.ts +427 -0
- package/src/develop/testRunner.ts +276 -0
- package/src/logging/logger.ts +73 -0
- package/src/loop/conversationLoop.ts +355 -0
- package/src/loop/phaseSummarizer.ts +114 -0
- package/src/mcp/mcpManager.ts +365 -0
- package/src/mcp/mcpTransport.ts +562 -0
- package/src/mcp/retryPolicy.ts +87 -0
- package/src/mcp/webSearch.ts +388 -0
- package/src/originalPrompts/design_thinking.md +178 -0
- package/src/originalPrompts/design_thinking_persona.md +76 -0
- package/src/originalPrompts/document_generator_example.md +77 -0
- package/src/originalPrompts/document_generator_persona.md +47 -0
- package/src/originalPrompts/facilitator_persona.md +125 -0
- package/src/originalPrompts/guardrails.md +47 -0
- package/src/phases/contextSummarizer.ts +154 -0
- package/src/phases/discoveryEnricher.ts +223 -0
- package/src/phases/phaseExtractors.ts +247 -0
- package/src/phases/phaseHandlers.ts +450 -0
- package/src/prompts/design.md +51 -0
- package/src/prompts/develop-boundary.md +51 -0
- package/src/prompts/develop.md +111 -0
- package/src/prompts/discover.md +58 -0
- package/src/prompts/ideate.md +56 -0
- package/src/prompts/plan.md +51 -0
- package/src/prompts/promptLoader.ts +198 -0
- package/src/prompts/select.md +47 -0
- package/src/prompts/summarize/README.md +8 -0
- package/src/prompts/summarize/design-summary.md +37 -0
- package/src/prompts/summarize/develop-summary.md +25 -0
- package/src/prompts/summarize/ideate-summary.md +27 -0
- package/src/prompts/summarize/plan-summary.md +27 -0
- package/src/prompts/summarize/select-summary.md +21 -0
- package/src/prompts/system.md +28 -0
- package/src/sessions/exportPaths.ts +28 -0
- package/src/sessions/exportWriter.ts +490 -0
- package/src/sessions/sessionManager.ts +119 -0
- package/src/sessions/sessionStore.ts +69 -0
- package/src/shared/activitySpinner.ts +108 -0
- package/src/shared/copilotClient.ts +291 -0
- package/src/shared/data/cards.json +1249 -0
- package/src/shared/data/cardsLoader.ts +70 -0
- package/src/shared/errorClassifier.ts +160 -0
- package/src/shared/events.ts +103 -0
- package/src/shared/markdownRenderer.ts +44 -0
- package/src/shared/schemas/session.ts +346 -0
- package/src/shared/tableRenderer.ts +28 -0
- package/src/types/marked-terminal.d.ts +5 -0
- package/src/vendor/chalk.ts +2 -0
- package/src/vendor/cli-table3.ts +3 -0
- package/src/vendor/commander.ts +2 -0
- package/src/vendor/marked-terminal.ts +3 -0
- package/src/vendor/marked.ts +2 -0
- package/src/vendor/ora.ts +2 -0
- package/src/vendor/pino.ts +3 -0
- package/src/vendor/zod.ts +3 -0
- package/tests/e2e/developE2e.spec.ts +152 -0
- package/tests/e2e/developFailureE2e.spec.ts +289 -0
- package/tests/e2e/developPty.spec.ts +86 -0
- package/tests/e2e/discoveryWebSearchRelevance.spec.ts +103 -0
- package/tests/e2e/harness.spec.ts +104 -0
- package/tests/e2e/mcpLive.spec.ts +149 -0
- package/tests/e2e/newSession.e2e.spec.ts +245 -0
- package/tests/e2e/ralphLoopEnrichmentComparison.spec.ts +70 -0
- package/tests/e2e/workiqEnrichment.spec.ts +72 -0
- package/tests/e2e/zava-assessment/agent-interaction-script.md +258 -0
- package/tests/e2e/zava-assessment/company-profile.md +98 -0
- package/tests/e2e/zava-assessment/expected-results-checklist.md +454 -0
- package/tests/e2e/zavaSimulation.spec.ts +511 -0
- package/tests/fixtures/completedSession.json +141 -0
- package/tests/fixtures/test-fixture-project/package-lock.json +1585 -0
- package/tests/fixtures/test-fixture-project/package.json +12 -0
- package/tests/fixtures/test-fixture-project/src/add.ts +3 -0
- package/tests/fixtures/test-fixture-project/tests/failing.test.ts +7 -0
- package/tests/fixtures/test-fixture-project/tests/hanging.test.ts +9 -0
- package/tests/fixtures/test-fixture-project/tests/passing.test.ts +13 -0
- package/tests/fixtures/test-fixture-project/vitest.config.ts +7 -0
- package/tests/integration/autoStartConversation.spec.ts +168 -0
- package/tests/integration/defaultCommand.spec.ts +179 -0
- package/tests/integration/directCommandNonTty.spec.ts +260 -0
- package/tests/integration/directCommandTty.spec.ts +185 -0
- package/tests/integration/discoveryEnrichmentFlow.spec.ts +209 -0
- package/tests/integration/exportArtifacts.spec.ts +232 -0
- package/tests/integration/exportFallbackFlow.spec.ts +115 -0
- package/tests/integration/mcpDegradationFlow.spec.ts +231 -0
- package/tests/integration/mcpTransportFlow.spec.ts +178 -0
- package/tests/integration/newSessionFlow.spec.ts +406 -0
- package/tests/integration/pocGithubMcp.spec.ts +224 -0
- package/tests/integration/pocLocalFallback.spec.ts +205 -0
- package/tests/integration/pocScaffold.spec.ts +220 -0
- package/tests/integration/ralphLoopFlow.spec.ts +430 -0
- package/tests/integration/ralphLoopPartial.spec.ts +416 -0
- package/tests/integration/resumeAndBacktrack.spec.ts +278 -0
- package/tests/integration/spinnerLifecycle.spec.ts +270 -0
- package/tests/integration/summarizationFlow.spec.ts +135 -0
- package/tests/integration/testRunnerReal.spec.ts +63 -0
- package/tests/integration/webSearchAgent.spec.ts +155 -0
- package/tests/live/copilotSdkLive.spec.ts +149 -0
- package/tests/live/zavaFullWorkshop.spec.ts +515 -0
- package/tests/setup/loadEnv.ts +5 -0
- package/tests/unit/cli/developCommand.spec.ts +679 -0
- package/tests/unit/cli/directCommands.spec.ts +325 -0
- package/tests/unit/cli/envLoader.spec.ts +73 -0
- package/tests/unit/cli/ioContext.spec.ts +148 -0
- package/tests/unit/cli/preflight.spec.ts +125 -0
- package/tests/unit/cli/statusCommand.spec.ts +134 -0
- package/tests/unit/cli/workshopClientFallback.spec.ts +100 -0
- package/tests/unit/cli/workshopCommand.spec.ts +378 -0
- package/tests/unit/config/vitestEnvSetup.spec.ts +24 -0
- package/tests/unit/develop/checkpointState.spec.ts +378 -0
- package/tests/unit/develop/codeGenerator.spec.ts +447 -0
- package/tests/unit/develop/githubMcpAdapter.spec.ts +283 -0
- package/tests/unit/develop/mcpContextEnricher.spec.ts +564 -0
- package/tests/unit/develop/outputValidator.spec.ts +134 -0
- package/tests/unit/develop/pocScaffolder.spec.ts +451 -0
- package/tests/unit/develop/ralphLoop.spec.ts +1439 -0
- package/tests/unit/develop/templateRegistry.spec.ts +106 -0
- package/tests/unit/develop/testRunner.spec.ts +294 -0
- package/tests/unit/infraBicep.spec.ts +116 -0
- package/tests/unit/infraDeploy.spec.ts +102 -0
- package/tests/unit/infraTeardown.spec.ts +77 -0
- package/tests/unit/logging/logger.spec.ts +50 -0
- package/tests/unit/loop/conversationLoop.spec.ts +719 -0
- package/tests/unit/loop/phaseSummarizer.spec.ts +169 -0
- package/tests/unit/loop/streamingMarkdown.spec.ts +180 -0
- package/tests/unit/mcp/mcpManager.spec.ts +336 -0
- package/tests/unit/mcp/mcpTransport.spec.ts +689 -0
- package/tests/unit/mcp/retryPolicy.spec.ts +278 -0
- package/tests/unit/mcp/timeoutValidation.spec.ts +55 -0
- package/tests/unit/mcp/webSearch.spec.ts +718 -0
- package/tests/unit/phases/contextSummarizer.spec.ts +158 -0
- package/tests/unit/phases/discoveryEnricher.repeatCalls.spec.ts +125 -0
- package/tests/unit/phases/discoveryEnricher.spec.ts +512 -0
- package/tests/unit/phases/phaseExtractors.spec.ts +406 -0
- package/tests/unit/phases/phaseHandlers.spec.ts +483 -0
- package/tests/unit/prompts/promptLoader.spec.ts +144 -0
- package/tests/unit/schemas/pocSchemas.spec.ts +457 -0
- package/tests/unit/schemas/session.spec.ts +328 -0
- package/tests/unit/sessions/exportPaths.spec.ts +38 -0
- package/tests/unit/sessions/exportWriter.spec.ts +737 -0
- package/tests/unit/sessions/sessionManager.spec.ts +174 -0
- package/tests/unit/sessions/sessionStore.spec.ts +136 -0
- package/tests/unit/shared/activitySpinner.spec.ts +211 -0
- package/tests/unit/shared/cardsLoader.spec.ts +89 -0
- package/tests/unit/shared/copilotClient.spec.ts +185 -0
- package/tests/unit/shared/errorClassifier.spec.ts +152 -0
- package/tests/unit/shared/events.spec.ts +71 -0
- package/tests/unit/shared/markdownRenderer.spec.ts +42 -0
- package/tests/unit/shared/markdownRendererChunks.spec.ts +83 -0
- package/tests/unit/shared/tableRenderer.spec.ts +38 -0
- package/tsconfig.json +20 -0
- package/vitest.config.ts +15 -0
- package/vitest.live.config.ts +19 -0
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
# Data Model: AI Foundry Search Service Deployment
|
|
2
|
+
|
|
3
|
+
**Feature**: 005-ai-search-deploy
|
|
4
|
+
**Date**: 2026-03-01
|
|
5
|
+
|
|
6
|
+
## Entities
|
|
7
|
+
|
|
8
|
+
### 1. FoundryDeploymentConfig
|
|
9
|
+
|
|
10
|
+
Configuration for the Bicep deployment. Captured as Bicep parameters and passed via the deployment script.
|
|
11
|
+
|
|
12
|
+
| Field | Type | Required | Default | Constraints | Notes |
|
|
13
|
+
|-------|------|----------|---------|-------------|-------|
|
|
14
|
+
| `subscriptionId` | string | yes | — | Valid Azure subscription GUID | From `az account show` or user input |
|
|
15
|
+
| `resourceGroupName` | string | yes | — | 1-90 chars, alphanumeric + `-_.()` | Auto-created if missing (FR-002) |
|
|
16
|
+
| `location` | string | no | `swedencentral` | Valid Azure region with Agent Service | FR-004 |
|
|
17
|
+
| `accountName` | string | no | `sofia-foundry` | 2-64 chars, `^[a-zA-Z0-9][a-zA-Z0-9_.-]*$` | Used to derive `customSubDomainName` |
|
|
18
|
+
| `projectName` | string | no | `sofia-project` | 2-64 chars | Child of account |
|
|
19
|
+
| `modelDeploymentName` | string | no | `gpt-4.1-mini` | Valid model deployment name | FR-012 |
|
|
20
|
+
| `modelName` | string | no | `gpt-4.1-mini` | Must support `web_search_preview` | See research.md R3 |
|
|
21
|
+
| `modelVersion` | string | no | `2025-04-14` | Valid model version | Pinned for reproducibility |
|
|
22
|
+
| `modelSkuName` | string | no | `GlobalStandard` | `GlobalStandard` or `Standard` | GlobalStandard for broadest availability |
|
|
23
|
+
| `modelSkuCapacity` | int | no | `1` | ≥1 (TPM in thousands) | Sufficient for workshop usage |
|
|
24
|
+
|
|
25
|
+
### 2. FoundryDeploymentOutput
|
|
26
|
+
|
|
27
|
+
Output produced by the deployment script. Used to configure the sofIA CLI.
|
|
28
|
+
|
|
29
|
+
| Field | Type | Description |
|
|
30
|
+
|-------|------|-------------|
|
|
31
|
+
| `projectEndpoint` | string | Foundry project endpoint URL (e.g., `https://<name>.services.ai.azure.com/api/projects/<project>`) |
|
|
32
|
+
| `modelDeploymentName` | string | Model deployment name (e.g., `gpt-4.1-mini`) |
|
|
33
|
+
| `resourceGroupName` | string | Resource group containing the deployment (for teardown) |
|
|
34
|
+
| `accountName` | string | Foundry account name |
|
|
35
|
+
|
|
36
|
+
### 3. WebSearchConfig (updated)
|
|
37
|
+
|
|
38
|
+
Runtime configuration for the `web.search` Copilot SDK tool. Replaces the current `WebSearchConfig` interface in `src/mcp/webSearch.ts`.
|
|
39
|
+
|
|
40
|
+
| Field | Type | Required | Source | Notes |
|
|
41
|
+
|-------|------|----------|--------|-------|
|
|
42
|
+
| `projectEndpoint` | string | yes | `FOUNDRY_PROJECT_ENDPOINT` env var | Replaces `endpoint` |
|
|
43
|
+
| `modelDeploymentName` | string | yes | `FOUNDRY_MODEL_DEPLOYMENT_NAME` env var | New field |
|
|
44
|
+
|
|
45
|
+
**Removed fields** (from current `WebSearchConfig`):
|
|
46
|
+
- `endpoint` → replaced by `projectEndpoint`
|
|
47
|
+
- `apiKey` → eliminated (using `DefaultAzureCredential`)
|
|
48
|
+
- `fetchFn` → eliminated (using SDK, not raw fetch)
|
|
49
|
+
|
|
50
|
+
### 4. AgentSession
|
|
51
|
+
|
|
52
|
+
Internal state for the ephemeral web search agent, managed within `webSearch.ts`. Not persisted — exists only in memory during a CLI session.
|
|
53
|
+
|
|
54
|
+
| Field | Type | Required | Notes |
|
|
55
|
+
|-------|------|----------|-------|
|
|
56
|
+
| `client` | `AIProjectClient` | yes | Created once per session |
|
|
57
|
+
| `openAIClient` | OpenAI client ref | yes | From `client.getOpenAIClient()` |
|
|
58
|
+
| `agentName` | string | yes | Agent name (e.g., `sofia-web-search`) |
|
|
59
|
+
| `agentVersion` | string | yes | Version returned by `createVersion()` |
|
|
60
|
+
| `conversationId` | string | yes | Thread/conversation for message exchange |
|
|
61
|
+
| `initialized` | boolean | yes | Tracks lazy initialization state |
|
|
62
|
+
|
|
63
|
+
**State transitions**:
|
|
64
|
+
```
|
|
65
|
+
[Uninitialized] → (first web.search call) → [Initialized] → (session end / error) → [Cleaned Up]
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
- **Uninitialized → Initialized**: On first `web.search` call, creates `AIProjectClient`, agent, and conversation.
|
|
69
|
+
- **Initialized → Cleaned Up**: On `destroyWebSearchSession()` call or `process.beforeExit`, deletes conversation and agent version.
|
|
70
|
+
- If cleanup fails, log warning but do not throw — stale agents will be cleaned up manually or by TTL.
|
|
71
|
+
|
|
72
|
+
### 5. WebSearchResult (unchanged)
|
|
73
|
+
|
|
74
|
+
The existing `WebSearchResult` interface remains structurally identical but gains citation data from `url_citation` annotations.
|
|
75
|
+
|
|
76
|
+
| Field | Type | Required | Notes |
|
|
77
|
+
|-------|------|----------|-------|
|
|
78
|
+
| `results` | `WebSearchResultItem[]` | yes | Structured search results |
|
|
79
|
+
| `sources` | `string[]` | no | Deduplicated citation URLs (FR-014) |
|
|
80
|
+
| `degraded` | boolean | no | `true` if Foundry unavailable/error |
|
|
81
|
+
| `error` | string | no | Error message when degraded |
|
|
82
|
+
|
|
83
|
+
### 6. WebSearchResultItem (updated)
|
|
84
|
+
|
|
85
|
+
| Field | Type | Required | Notes |
|
|
86
|
+
|-------|------|----------|-------|
|
|
87
|
+
| `title` | string | yes | Page title (extracted from citation or response) |
|
|
88
|
+
| `url` | string | yes | Source URL from `url_citation` annotation |
|
|
89
|
+
| `snippet` | string | yes | Relevant text excerpt |
|
|
90
|
+
|
|
91
|
+
### 7. LegacyEnvVarError
|
|
92
|
+
|
|
93
|
+
Not a data model entity but a specific error condition (FR-016).
|
|
94
|
+
|
|
95
|
+
| Condition | Action |
|
|
96
|
+
|-----------|--------|
|
|
97
|
+
| `SOFIA_FOUNDRY_AGENT_ENDPOINT` is set | Emit error: "Legacy env var detected. Migrate to FOUNDRY_PROJECT_ENDPOINT. See docs/environment.md" |
|
|
98
|
+
| `SOFIA_FOUNDRY_AGENT_KEY` is set | Emit error: "Legacy env var detected. API key auth is no longer used. See docs/environment.md" |
|
|
99
|
+
|
|
100
|
+
Checked during preflight (`preflight.ts`). Fails the preflight check with `required: true`.
|
|
101
|
+
|
|
102
|
+
## Relationships
|
|
103
|
+
|
|
104
|
+
```
|
|
105
|
+
FoundryDeploymentConfig ──(deploys to)──> Azure Resources
|
|
106
|
+
│
|
|
107
|
+
├── Foundry Account
|
|
108
|
+
│ ├── Model Deployment
|
|
109
|
+
│ └── Account Capability Host
|
|
110
|
+
└── Foundry Project
|
|
111
|
+
└── Project Capability Host
|
|
112
|
+
|
|
113
|
+
FoundryDeploymentOutput ──(configures)──> WebSearchConfig (runtime)
|
|
114
|
+
│
|
|
115
|
+
└── AgentSession (lazy, in-memory)
|
|
116
|
+
│
|
|
117
|
+
├── AIProjectClient
|
|
118
|
+
├── Agent (ephemeral)
|
|
119
|
+
└── Conversation
|
|
120
|
+
│
|
|
121
|
+
└── WebSearchResult + citations
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
## Validation Rules
|
|
125
|
+
|
|
126
|
+
1. **`projectEndpoint`** must match pattern: `https://*.services.ai.azure.com/api/projects/*`
|
|
127
|
+
2. **`modelDeploymentName`** must be non-empty string, no whitespace
|
|
128
|
+
3. **Legacy env vars**: Presence of `SOFIA_FOUNDRY_AGENT_ENDPOINT` or `SOFIA_FOUNDRY_AGENT_KEY` is a hard error (FR-016)
|
|
129
|
+
4. **Bicep parameters**: `accountName` must be unique within the resource group; `customSubDomainName` must be globally unique
|
|
130
|
+
5. **Agent cleanup**: Must attempt cleanup even on error; log warnings but do not throw on cleanup failure
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
# Implementation Plan: AI Foundry Search Service Deployment
|
|
2
|
+
|
|
3
|
+
**Branch**: `005-ai-search-deploy` | **Date**: 2026-03-01 | **Spec**: [spec.md](spec.md)
|
|
4
|
+
**Input**: Feature specification from `/specs/005-ai-search-deploy/spec.md`
|
|
5
|
+
|
|
6
|
+
## Summary
|
|
7
|
+
|
|
8
|
+
Provide one-command deployment of Azure AI Foundry infrastructure (account, project, model deployment) via Bicep + shell script, and migrate the sofIA CLI's `web.search` tool from raw HTTP + API key (`SOFIA_FOUNDRY_AGENT_ENDPOINT`/`SOFIA_FOUNDRY_AGENT_KEY`) to the `@azure/ai-projects` SDK with `DefaultAzureCredential` auth and ephemeral `web_search_preview` agents. Includes teardown, prerequisite validation, and clean-break migration from legacy env vars.
|
|
9
|
+
|
|
10
|
+
## Technical Context
|
|
11
|
+
|
|
12
|
+
**Language/Version**: Node.js 20 LTS + TypeScript 5.3, Bash (deployment scripts), Bicep (IaC)
|
|
13
|
+
**Primary Dependencies**: `@github/copilot-sdk ^0.1.28`, `@azure/ai-projects` (new), `@azure/identity` (new), `dotenv` (new), `zod ^4.3.6`
|
|
14
|
+
**Storage**: N/A (stateless infrastructure provisioning; session state handled by existing `SessionStore`)
|
|
15
|
+
**Testing**: Vitest 4.x (unit + integration), TDD Red→Green→Review per constitution
|
|
16
|
+
**Target Platform**: CLI — Linux, macOS, Windows (WSL/Git Bash); Azure for infrastructure deployment
|
|
17
|
+
**Project Type**: CLI tool + Infrastructure-as-Code
|
|
18
|
+
**Performance Goals**: Web search query returns grounded results with citations within 10 seconds (SC-003)
|
|
19
|
+
**Constraints**: Deploy completes in <15 minutes (SC-001); teardown in <10 minutes (SC-004); agent lifecycle is ephemeral (created/deleted per CLI session)
|
|
20
|
+
**Scale/Scope**: Workshop/PoC usage — small number of queries per session; single resource group deployment
|
|
21
|
+
|
|
22
|
+
## Constitution Check
|
|
23
|
+
|
|
24
|
+
_GATE: Must pass before Phase 0 research. Re-check after Phase 1 design._
|
|
25
|
+
|
|
26
|
+
Default gates for this repository (sofIA Copilot CLI) — derived from `.specify/memory/constitution.md`:
|
|
27
|
+
|
|
28
|
+
- **Outcome-first discovery**: ✅ PASS — Deploys the web search backend that enables real-time company/industry research during the Discover phase (Step 1). Directly ties to the workshop's core value: grounding ideation in real-world context.
|
|
29
|
+
- **Secure-by-default**: ✅ PASS — Migrates from API key auth (`SOFIA_FOUNDRY_AGENT_KEY`) to `DefaultAzureCredential` (least privilege, no secrets in env vars). Legacy key vars trigger an error, not silent fallback. Logger redaction remains.
|
|
30
|
+
- **Node.js + TypeScript**: ✅ PASS — CLI integration uses `@azure/ai-projects` + `@azure/identity` TypeScript SDKs. Bicep + Bash for infrastructure only (not runtime code).
|
|
31
|
+
- **MCP-first**: ⚠️ EXCEPTION — The Foundry Agent Service does not expose an MCP server; the `@azure/ai-projects` SDK is the only supported integration surface. The tool is still registered as a Copilot SDK tool (`web.search`) and used by MCP-aware phases. Documented in Complexity Tracking.
|
|
32
|
+
- **Test-first (NON-NEGOTIABLE)**: ✅ PASS — All SDK integration code must follow Red→Green→Review. Unit tests for config validation, credential detection, and migration error. Integration tests with fakes for agent create/query/delete lifecycle. Bash deployment script validated via dry-run tests.
|
|
33
|
+
- **CLI transparency**: ✅ PASS — Deployment script streams progress (`az deployment` output, prerequisite check results, resource provisioning status). CLI surfaces web search availability/degradation to user. Teardown confirms resource deletion.
|
|
34
|
+
|
|
35
|
+
## Project Structure
|
|
36
|
+
|
|
37
|
+
### Documentation (this feature)
|
|
38
|
+
|
|
39
|
+
```text
|
|
40
|
+
specs/005-ai-search-deploy/
|
|
41
|
+
├── plan.md # This file
|
|
42
|
+
├── research.md # Phase 0 output
|
|
43
|
+
├── data-model.md # Phase 1 output
|
|
44
|
+
├── quickstart.md # Phase 1 output
|
|
45
|
+
├── contracts/ # Phase 1 output
|
|
46
|
+
│ └── web-search-tool.md
|
|
47
|
+
└── tasks.md # Phase 2 output (created by /speckit.tasks)
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### Source Code (repository root)
|
|
51
|
+
|
|
52
|
+
```text
|
|
53
|
+
infra/ # NEW — Infrastructure-as-Code
|
|
54
|
+
├── main.bicep # Subscription-scoped entry point (resource group + module)
|
|
55
|
+
├── resources.bicep # Resource-group-scoped module (account, model, project, capability hosts)
|
|
56
|
+
├── main.bicepparam # Default parameters (swedencentral, gpt-4.1-mini)
|
|
57
|
+
├── deploy.sh # One-command deployment script (FR-002), writes .env (FR-018)
|
|
58
|
+
└── teardown.sh # Resource group deletion (FR-007)
|
|
59
|
+
|
|
60
|
+
src/
|
|
61
|
+
├── mcp/
|
|
62
|
+
│ └── webSearch.ts # MODIFIED — Migrate from raw HTTP + API key
|
|
63
|
+
│ # to @azure/ai-projects SDK + DefaultAzureCredential
|
|
64
|
+
│ # + ephemeral agent lifecycle (create/query/delete)
|
|
65
|
+
├── cli/
|
|
66
|
+
│ ├── envLoader.ts # NEW — Loads .env file at startup via dotenv (FR-017)
|
|
67
|
+
│ ├── index.ts # MODIFIED — Calls loadEnvFile() at startup
|
|
68
|
+
│ └── preflight.ts # MODIFIED — Add legacy env var detection check (FR-016)
|
|
69
|
+
├── shared/
|
|
70
|
+
│ └── copilotClient.ts # UNCHANGED — ToolDefinition interface still used
|
|
71
|
+
└── develop/
|
|
72
|
+
└── mcpContextEnricher.ts # MODIFIED — Update isWebSearchConfigured() import
|
|
73
|
+
|
|
74
|
+
docs/
|
|
75
|
+
└── environment.md # MODIFIED — Update env var documentation
|
|
76
|
+
|
|
77
|
+
tests/
|
|
78
|
+
├── unit/
|
|
79
|
+
│ ├── webSearch.spec.ts # NEW — Config validation, credential auth, migration error
|
|
80
|
+
│ └── infraDeploy.spec.ts # NEW — Deploy script parameter validation (dry-run)
|
|
81
|
+
└── integration/
|
|
82
|
+
└── webSearchAgent.spec.ts # NEW — Ephemeral agent lifecycle with fakes
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
**Structure Decision**: Single project layout (Option 1) with a new `infra/` directory at the repository root for Bicep templates and deployment scripts. This follows Azure conventions and keeps infrastructure separate from application code. The `src/mcp/webSearch.ts` module is modified in-place (not moved) since it already has the correct responsibility boundary.
|
|
86
|
+
|
|
87
|
+
## Complexity Tracking
|
|
88
|
+
|
|
89
|
+
> **Fill ONLY if Constitution Check has violations that must be justified**
|
|
90
|
+
|
|
91
|
+
| Violation | Why Needed | Simpler Alternative Rejected Because |
|
|
92
|
+
| ------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------ |
|
|
93
|
+
| MCP-first exception: direct SDK call to Foundry Agent Service | Azure AI Foundry Agent Service has no MCP server; `@azure/ai-projects` is the only supported client SDK. The tool is still exposed as a Copilot SDK tool and consumed by MCP-aware phases. | No MCP adapter exists for this service. Writing a custom MCP proxy would add complexity with no ecosystem benefit. |
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
# Quickstart: AI Foundry Search Service Deployment
|
|
2
|
+
|
|
3
|
+
**Feature**: 005-ai-search-deploy
|
|
4
|
+
**Date**: 2026-03-01
|
|
5
|
+
|
|
6
|
+
## Prerequisites
|
|
7
|
+
|
|
8
|
+
- **Azure CLI** installed and logged in (`az login`)
|
|
9
|
+
- **Azure subscription** with Owner or Contributor permissions
|
|
10
|
+
- **Node.js 20+** for running the sofIA CLI
|
|
11
|
+
- **Bash shell** (Linux, macOS, or Windows WSL/Git Bash)
|
|
12
|
+
|
|
13
|
+
## 1. Deploy the Infrastructure
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
# From the repository root (uses your current az CLI subscription)
|
|
17
|
+
./infra/deploy.sh --resource-group sofia-workshop-rg
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
This provisions:
|
|
21
|
+
|
|
22
|
+
- Azure AI Foundry account with SystemAssigned managed identity
|
|
23
|
+
- Model deployment (`gpt-4.1-mini` by default)
|
|
24
|
+
- Foundry project with Agent Service capability enabled
|
|
25
|
+
|
|
26
|
+
**Customize** (optional):
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
./infra/deploy.sh \
|
|
30
|
+
--resource-group sofia-workshop-rg \
|
|
31
|
+
--subscription <id> \
|
|
32
|
+
--location eastus \
|
|
33
|
+
--account-name my-foundry \
|
|
34
|
+
--model gpt-4o-mini
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## 2. Configure sofIA
|
|
38
|
+
|
|
39
|
+
After deployment, the script automatically writes the required environment variables to a `.env` file in the workspace root:
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
FOUNDRY_PROJECT_ENDPOINT="https://sofia-foundry-abc123.services.ai.azure.com/api/projects/sofia-project"
|
|
43
|
+
FOUNDRY_MODEL_DEPLOYMENT_NAME="gpt-4.1-mini"
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
The sofIA CLI loads this `.env` file automatically at startup — no manual configuration needed.
|
|
47
|
+
|
|
48
|
+
> **Note**: No API key needed. sofIA authenticates using your Azure login credentials (`az login`).
|
|
49
|
+
|
|
50
|
+
## 3. Verify Web Search
|
|
51
|
+
|
|
52
|
+
Start a sofIA workshop session:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
sofia workshop --new-session
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
During the **Discover** phase, describe a real company. sofIA will automatically invoke the `web.search` tool to research the company, its competitors, and industry trends. Search results include clickable source URLs.
|
|
59
|
+
|
|
60
|
+
## 4. Teardown (When Done)
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
./infra/teardown.sh --resource-group sofia-workshop-rg
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
This deletes the resource group and all contained Azure resources to stop billing.
|
|
67
|
+
|
|
68
|
+
## Migrating from Legacy Configuration
|
|
69
|
+
|
|
70
|
+
If you previously used `SOFIA_FOUNDRY_AGENT_ENDPOINT` / `SOFIA_FOUNDRY_AGENT_KEY`:
|
|
71
|
+
|
|
72
|
+
1. **Remove** the old variables from your environment
|
|
73
|
+
2. **Set** the new variables (`FOUNDRY_PROJECT_ENDPOINT`, `FOUNDRY_MODEL_DEPLOYMENT_NAME`)
|
|
74
|
+
3. **Ensure** you are logged in via `az login`
|
|
75
|
+
|
|
76
|
+
The CLI will display an error if it detects the old variables, guiding you through the migration.
|
|
77
|
+
|
|
78
|
+
## Troubleshooting
|
|
79
|
+
|
|
80
|
+
| Symptom | Cause | Fix |
|
|
81
|
+
| ---------------------------------------- | ------------------------------------ | --------------------------------------------------------------------------------------------------------- |
|
|
82
|
+
| "Web search not configured" | Env vars not set | Set `FOUNDRY_PROJECT_ENDPOINT` and `FOUNDRY_MODEL_DEPLOYMENT_NAME` |
|
|
83
|
+
| "Azure authentication failed" | Not logged in or token expired | Run `az login` |
|
|
84
|
+
| "Legacy web search env vars detected" | Old `SOFIA_FOUNDRY_*` vars still set | Remove them, set new vars |
|
|
85
|
+
| Deploy fails: "subscription not found" | Wrong subscription selected | Run `az account set --subscription <id>` |
|
|
86
|
+
| Deploy fails: "insufficient permissions" | Not Owner/Contributor | Ask an admin to grant access |
|
|
87
|
+
| Web search returns no results | Model didn't use web search | This is normal — the model decides when to search |
|
|
88
|
+
| "Web search disabled at subscription" | Admin blocked the tool | Run `az feature unregister --name OpenAI.BlockedTools.web_search --namespace Microsoft.CognitiveServices` |
|
|
89
|
+
|
|
90
|
+
## Cost Expectations
|
|
91
|
+
|
|
92
|
+
- **Foundry account**: Free (billing is per-usage)
|
|
93
|
+
- **Model deployment**: Pay-per-token for `gpt-4.1-mini` queries
|
|
94
|
+
- **Grounding with Bing Search**: Usage-based ([pricing](https://www.microsoft.com/bing/apis/grounding-pricing))
|
|
95
|
+
- **Typical workshop**: A few dozen web search queries — minimal cost
|
|
96
|
+
- **Teardown immediately after workshop** to avoid idle resource charges
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
# Research: AI Foundry Search Service Deployment
|
|
2
|
+
|
|
3
|
+
**Feature**: 005-ai-search-deploy
|
|
4
|
+
**Date**: 2026-03-01
|
|
5
|
+
**Status**: Complete — all NEEDS CLARIFICATION items resolved
|
|
6
|
+
|
|
7
|
+
## R1: Azure AI Foundry Bicep Resource Types
|
|
8
|
+
|
|
9
|
+
**Decision**: Use `Microsoft.CognitiveServices` resource provider (API version `2025-06-01`) with 5 resources for the basic agent setup.
|
|
10
|
+
|
|
11
|
+
**Rationale**: The basic (Microsoft-managed) setup minimizes complexity — no BYO Storage, Key Vault, Cosmos DB, or AI Search needed. Microsoft manages these behind the scenes. This aligns with FR-008 (basic agent setup) and the workshop/PoC use case.
|
|
12
|
+
|
|
13
|
+
**Required Resources**:
|
|
14
|
+
|
|
15
|
+
| # | Bicep Resource Type | Purpose |
|
|
16
|
+
|---|---------------------|---------|
|
|
17
|
+
| 1 | `Microsoft.CognitiveServices/accounts` (kind: `AIServices`) | Foundry account with `allowProjectManagement: true` and `customSubDomainName` |
|
|
18
|
+
| 2 | `Microsoft.CognitiveServices/accounts/deployments` | Model deployment (default: `gpt-4.1-mini`, version `2025-04-14`, SKU `GlobalStandard`) |
|
|
19
|
+
| 3 | `Microsoft.CognitiveServices/accounts/projects` | Foundry project — provides the endpoint URL |
|
|
20
|
+
| 4 | `Microsoft.CognitiveServices/accounts/capabilityHosts` | Account-level capability host (`capabilityHostKind: 'Agents'`) |
|
|
21
|
+
| 5 | `Microsoft.CognitiveServices/accounts/projects/capabilityHosts` | Project-level capability host (basic setup = empty connections) |
|
|
22
|
+
|
|
23
|
+
**Alternatives considered**:
|
|
24
|
+
- **Azure Verified Module (`br/public:avm/ptn/ai-ml/ai-foundry`)**: Less transparent, harder to document each resource per FR-011. Rejected for PoC simplicity.
|
|
25
|
+
- **Standard agent setup (BYO resources)**: Requires Cosmos DB, Storage, Key Vault, AI Search, multiple role assignments. Over-engineered for workshop scenario.
|
|
26
|
+
|
|
27
|
+
**Gotchas**:
|
|
28
|
+
- `customSubDomainName` is mandatory and must be globally unique — generate with a suffix (e.g., `sofia-<uniqueString>`)
|
|
29
|
+
- `allowProjectManagement: true` is required for child projects
|
|
30
|
+
- Capability hosts cannot be updated after creation; must delete and recreate
|
|
31
|
+
- Account capability host must be created before project capability host (`dependsOn`)
|
|
32
|
+
- Model deployment must exist before the account capability host references it
|
|
33
|
+
|
|
34
|
+
## R2: Model Deployment Configuration
|
|
35
|
+
|
|
36
|
+
**Decision**: Default to `gpt-4.1-mini` with `GlobalStandard` SKU, version `2025-04-14`.
|
|
37
|
+
|
|
38
|
+
**Rationale**: `gpt-4.1-mini` supports `web_search_preview` and is cost-effective for workshop scenarios. `GlobalStandard` SKU routes to the nearest available region, providing the broadest availability. The spec (FR-012) explicitly requires `gpt-4.1-mini` as default.
|
|
39
|
+
|
|
40
|
+
**Alternatives considered**:
|
|
41
|
+
- **`gpt-4.1`**: More capable but higher cost. Unnecessary for web search query routing.
|
|
42
|
+
- **`gpt-4o-mini`**: Also supported but `gpt-4.1-mini` is newer and matches the spec decision.
|
|
43
|
+
- **`Standard` SKU**: Regional-only deployment; model must be available in the exact account region. More restrictive than `GlobalStandard`.
|
|
44
|
+
|
|
45
|
+
## R3: `web_search_preview` Region and Model Support
|
|
46
|
+
|
|
47
|
+
**Decision**: No region restrictions — `web_search_preview` is available in all 23 Agent Service regions, including `swedencentral`.
|
|
48
|
+
|
|
49
|
+
**Rationale**: Research confirms web search is universally available across all Agent Service regions. No deployment script region validation needed beyond basic AI Services availability.
|
|
50
|
+
|
|
51
|
+
**Supported model families**: gpt-4.1, gpt-4.1-mini, gpt-4.1-nano, gpt-4o, gpt-4o-mini, o3, o4-mini, o3-mini, o1, gpt-5. Notably NOT supported: DeepSeek, Llama, Grok.
|
|
52
|
+
|
|
53
|
+
## R4: @azure/ai-projects SDK Integration Pattern
|
|
54
|
+
|
|
55
|
+
**Decision**: Use `@azure/ai-projects@beta` (v2.x preview) with `AIProjectClient`, `agents.createVersion()`, and OpenAI-style `responses.create()` pattern.
|
|
56
|
+
|
|
57
|
+
**Rationale**: This is the current official SDK documented at learn.microsoft.com for the Foundry Agent Service. It replaces the older `@azure/ai-agents` package and provides a unified API for agent lifecycle management.
|
|
58
|
+
|
|
59
|
+
**Key API Pattern**:
|
|
60
|
+
|
|
61
|
+
```typescript
|
|
62
|
+
import { DefaultAzureCredential } from "@azure/identity";
|
|
63
|
+
import { AIProjectClient } from "@azure/ai-projects";
|
|
64
|
+
|
|
65
|
+
// 1. Create client
|
|
66
|
+
const project = new AIProjectClient(endpoint, new DefaultAzureCredential());
|
|
67
|
+
const openAIClient = await project.getOpenAIClient();
|
|
68
|
+
|
|
69
|
+
// 2. Create ephemeral agent with web search
|
|
70
|
+
const agent = await project.agents.createVersion("sofia-web-search", {
|
|
71
|
+
kind: "prompt",
|
|
72
|
+
model: deploymentName,
|
|
73
|
+
instructions: "You are a web search assistant...",
|
|
74
|
+
tools: [{ type: "web_search_preview" }],
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
// 3. Create conversation, send message, get response
|
|
78
|
+
const conversation = await openAIClient.conversations.create();
|
|
79
|
+
const response = await openAIClient.responses.create(
|
|
80
|
+
{ conversation: conversation.id, input: query },
|
|
81
|
+
{ body: { agent: { name: agent.name, type: "agent_reference" } } },
|
|
82
|
+
);
|
|
83
|
+
|
|
84
|
+
// 4. Extract citations
|
|
85
|
+
for (const item of response.output) {
|
|
86
|
+
if (item.type === "message") {
|
|
87
|
+
for (const content of item.content) {
|
|
88
|
+
if (content.type === "output_text" && content.annotations) {
|
|
89
|
+
for (const annotation of content.annotations) {
|
|
90
|
+
if (annotation.type === "url_citation") {
|
|
91
|
+
// { url, start_index, end_index }
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// 5. Cleanup
|
|
100
|
+
await openAIClient.conversations.delete(conversation.id);
|
|
101
|
+
await project.agents.deleteVersion(agent.name, agent.version);
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
**Alternatives considered**:
|
|
105
|
+
- **`@azure/ai-agents` (classic API)**: Older `AgentsClient` with threads/runs pattern. Still works but being superseded by `AIProjectClient`.
|
|
106
|
+
- **Raw HTTP POST (current pattern)**: Requires manual token management, no built-in credential chain. Rejected for security and maintainability.
|
|
107
|
+
|
|
108
|
+
## R5: Authentication Migration
|
|
109
|
+
|
|
110
|
+
**Decision**: Replace API key auth (`SOFIA_FOUNDRY_AGENT_KEY`) with `DefaultAzureCredential` from `@azure/identity`.
|
|
111
|
+
|
|
112
|
+
**Rationale**: `DefaultAzureCredential` provides a credential chain that automatically discovers the best available credential (Azure CLI → Managed Identity → Environment). Eliminates secrets from environment variables. Aligns with FR-013 and the secure-by-default constitution principle.
|
|
113
|
+
|
|
114
|
+
**Credential chain order** (what `DefaultAzureCredential` tries):
|
|
115
|
+
1. `EnvironmentCredential` (`AZURE_CLIENT_ID` + `AZURE_TENANT_ID` + `AZURE_CLIENT_SECRET`)
|
|
116
|
+
2. `WorkloadIdentityCredential` (Kubernetes)
|
|
117
|
+
3. `ManagedIdentityCredential` (Azure-hosted)
|
|
118
|
+
4. `AzureDeveloperCliCredential` (`azd auth login`)
|
|
119
|
+
5. `AzureCliCredential` (`az login`)
|
|
120
|
+
6. `AzurePowerShellCredential` (`Connect-AzAccount`)
|
|
121
|
+
|
|
122
|
+
**Required RBAC role**: `Azure AI User` at the Foundry project scope.
|
|
123
|
+
|
|
124
|
+
**Environment variables (new)**:
|
|
125
|
+
- `FOUNDRY_PROJECT_ENDPOINT` — e.g. `https://<name>.services.ai.azure.com/api/projects/<project>`
|
|
126
|
+
- `FOUNDRY_MODEL_DEPLOYMENT_NAME` — e.g. `gpt-4.1-mini`
|
|
127
|
+
|
|
128
|
+
**Migration behavior** (FR-016): If legacy `SOFIA_FOUNDRY_AGENT_ENDPOINT` or `SOFIA_FOUNDRY_AGENT_KEY` are detected, CLI emits an error message with migration instructions. Old vars are never used.
|
|
129
|
+
|
|
130
|
+
## R6: Deployment Script Design
|
|
131
|
+
|
|
132
|
+
**Decision**: Bash script (`deploy.sh`) wrapping `az deployment sub create` for subscription-level Bicep deployment, with prerequisite validation.
|
|
133
|
+
|
|
134
|
+
**Rationale**: Bash is portable across Linux, macOS, and WSL/Git Bash (FR-010). Subscription-level deployment is needed because the script auto-creates the resource group (FR-002). `az deployment sub create` handles this natively.
|
|
135
|
+
|
|
136
|
+
**Script flow**:
|
|
137
|
+
1. Validate prerequisites: `az` CLI installed, user logged in, subscription accessible
|
|
138
|
+
2. Accept parameters: subscription ID, resource group name, region (default: `swedencentral`), account name, model (default: `gpt-4.1-mini`)
|
|
139
|
+
3. Generate unique subdomain name from account name
|
|
140
|
+
4. Run `az deployment sub create` with Bicep template
|
|
141
|
+
5. Query outputs: project endpoint URL, model deployment name
|
|
142
|
+
6. Print configuration instructions for `FOUNDRY_PROJECT_ENDPOINT` and `FOUNDRY_MODEL_DEPLOYMENT_NAME`
|
|
143
|
+
|
|
144
|
+
**Teardown script** (`teardown.sh`):
|
|
145
|
+
1. Accept resource group name
|
|
146
|
+
2. Validate resource group exists (informational exit if not)
|
|
147
|
+
3. Run `az group delete --yes --no-wait` for non-blocking deletion
|
|
148
|
+
|
|
149
|
+
## R7: Copilot SDK Tool Registration
|
|
150
|
+
|
|
151
|
+
**Decision**: Keep the existing `web.search` tool name and `ToolDefinition` interface. The handler function internally calls the Foundry Agent Service SDK instead of raw HTTP.
|
|
152
|
+
|
|
153
|
+
**Rationale**: The Copilot SDK tool contract (tool name, parameters, handler signature) is unchanged — only the implementation behind `createWebSearchTool()` changes. This maintains backward compatibility with prompt references (`discover.md`, `develop.md`) and the `mcpContextEnricher.ts` integration.
|
|
154
|
+
|
|
155
|
+
**Integration pattern**: The `createWebSearchTool()` factory creates the `AIProjectClient` and an ephemeral agent on first call. The agent and conversation are reused for the session lifetime. On session end (or error), the agent and conversation are cleaned up.
|
|
156
|
+
|
|
157
|
+
**Alternatives considered**:
|
|
158
|
+
- **Create agent per query**: Too expensive — agent creation has latency. Rejected.
|
|
159
|
+
- **Persistent agent (not deleted)**: Would accumulate agents in the Foundry project. Rejected per FR-015 (ephemeral lifecycle).
|
|
160
|
+
- **Lazy initialization**: Agent created on first `web.search` call, not on session start. This avoids agent creation overhead when web search is never invoked. **This is the chosen pattern** — create lazily, delete on session end.
|
|
161
|
+
|
|
162
|
+
## R8: Ephemeral Agent Lifecycle
|
|
163
|
+
|
|
164
|
+
**Decision**: Lazy creation on first web search call, automatic deletion on process exit or session end.
|
|
165
|
+
|
|
166
|
+
**Rationale**: Creating the agent at session start adds unnecessary latency if web search is never used. Creating on first call amortizes the cost and ensures cleanup happens reliably.
|
|
167
|
+
|
|
168
|
+
**Implementation**:
|
|
169
|
+
- `webSearch.ts` maintains a module-level `AgentSession` (agent ID, conversation ID, client references)
|
|
170
|
+
- First call to `web.search` handler triggers `AgentSession.initialize()` — creates agent + conversation
|
|
171
|
+
- Subsequent calls reuse the same agent and conversation
|
|
172
|
+
- `AgentSession.cleanup()` deletes the conversation and agent version
|
|
173
|
+
- Register cleanup via `process.on('beforeExit', ...)` and expose a `destroyWebSearchSession()` for explicit cleanup from the workshop command
|
|
174
|
+
|
|
175
|
+
## R9: New Dependencies Impact
|
|
176
|
+
|
|
177
|
+
**Decision**: Add `@azure/ai-projects@beta` and `@azure/identity` as production dependencies.
|
|
178
|
+
|
|
179
|
+
**Impact assessment**:
|
|
180
|
+
- `@azure/identity` is well-maintained (v4.13.0+), widely used, no known security issues
|
|
181
|
+
- `@azure/ai-projects@beta` is in preview — API may change. Pin to a specific beta version for stability
|
|
182
|
+
- Both are tree-shakeable ESM packages
|
|
183
|
+
- No conflicting peer dependencies with existing packages (`commander`, `zod`, `pino`, etc.)
|
|
184
|
+
- TypeScript types are included in both packages
|
|
185
|
+
|
|
186
|
+
**Alternatives considered**:
|
|
187
|
+
- **Optional dependencies**: Would complicate the build. Since web search is a core workshop tool, these should be required dependencies.
|