Skip to content

Commit 6af2d71

Browse files
authored
Merge pull request microsoft#354 from microsoft/macae-plan-api
create_plan api
2 parents 1daea22 + 6541bd5 commit 6af2d71

19 files changed

Lines changed: 387 additions & 59 deletions

NEW_ENDPOINTS_SUMMARY.md

Whitespace-only changes.

TEAM_CONFIG_UPLOAD_README.md

Whitespace-only changes.

docs/CustomizingAzdParameters.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ By default this template will use the environment name as the prefix to prevent
1818
| `AZURE_ENV_MODEL_CAPACITY` | int | `150` | Sets the GPT model capacity. |
1919
| `AZURE_ENV_IMAGETAG` | string | `latest` | Docker image tag used for container deployments. |
2020
| `AZURE_ENV_ENABLE_TELEMETRY` | bool | `true` | Enables telemetry for monitoring and diagnostics. |
21-
| `AZURE_ENV_LOG_ANALYTICS_WORKSPACE_ID` | string | `<Existing Workspace Id>` | Set this if you want to reuse an existing Log Analytics Workspace instead of creating a new one. |
21+
| `AZURE_ENV_LOG_ANALYTICS_WORKSPACE_ID` | string | Guide to get your [Existing Workspace ID](/docs/re-use-log-analytics.md) | Set this if you want to reuse an existing Log Analytics Workspace instead of creating a new one. |
2222
---
2323

2424
## How to Set a Parameter

infra/modules/role.bicep

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ resource aiUserAccessFoundry 'Microsoft.Authorization/roleAssignments@2022-04-01
2929
properties: {
3030
roleDefinitionId: aiUser.id
3131
principalId: principalId
32+
principalType: 'ServicePrincipal'
3233
}
3334
}
3435

@@ -38,6 +39,7 @@ resource aiDeveloperAccessFoundry 'Microsoft.Authorization/roleAssignments@2022-
3839
properties: {
3940
roleDefinitionId: aiDeveloper.id
4041
principalId: principalId
42+
principalType: 'ServicePrincipal'
4143
}
4244
}
4345

@@ -47,5 +49,6 @@ resource cognitiveServiceOpenAIUserAccessFoundry 'Microsoft.Authorization/roleAs
4749
properties: {
4850
roleDefinitionId: cognitiveServiceOpenAIUser.id
4951
principalId: principalId
52+
principalType: 'ServicePrincipal'
5053
}
5154
}

infra/old/deploy_ai_foundry.bicep

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,7 @@ resource aiDevelopertoAIProject 'Microsoft.Authorization/roleAssignments@2022-04
169169
properties: {
170170
roleDefinitionId: aiDeveloper.id
171171
principalId: aiHubProject.identity.principalId
172+
principalType: 'ServicePrincipal'
172173
}
173174
}
174175

infra/old/main.bicep

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -680,6 +680,7 @@ module aiFoundryStorageAccount 'br/public:avm/res/storage/storage-account:0.18.2
680680
{
681681
principalId: userAssignedIdentity.outputs.principalId
682682
roleDefinitionIdOrName: 'Storage Blob Data Contributor'
683+
principalType: 'ServicePrincipal'
683684
}
684685
]
685686
}
@@ -760,6 +761,7 @@ module aiFoundryAiProject 'br/public:avm/res/machine-learning-services/workspace
760761
principalId: containerApp.outputs.?systemAssignedMIPrincipalId!
761762
// Assigning the role with the role name instead of the role ID freezes the deployment at this point
762763
roleDefinitionIdOrName: '64702f94-c441-49e6-a78b-ef80e0188fee' //'Azure AI Developer'
764+
principalType: 'ServicePrincipal'
763765
}
764766
]
765767
}

infra/scripts/quota_check_params.sh

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -164,11 +164,7 @@ for REGION in "${REGIONS[@]}"; do
164164
FOUND=false
165165
INSUFFICIENT_QUOTA=false
166166

167-
if [ "$MODEL_NAME" = "text-embedding-ada-002" ]; then
168-
MODEL_TYPES=("openai.standard.$MODEL_NAME")
169-
else
170-
MODEL_TYPES=("openai.standard.$MODEL_NAME" "openai.globalstandard.$MODEL_NAME")
171-
fi
167+
MODEL_TYPES=("openai.standard.$MODEL_NAME" "openai.globalstandard.$MODEL_NAME")
172168

173169
for MODEL_TYPE in "${MODEL_TYPES[@]}"; do
174170
FOUND=false

infra/scripts/validate_model_quota.ps1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
param (
22
[string]$Location,
33
[string]$Model,
4-
[string]$DeploymentType = "Standard",
4+
[string]$DeploymentType = "GlobalStandard",
55
[int]$Capacity
66
)
77

infra/scripts/validate_model_quota.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
LOCATION=""
44
MODEL=""
5-
DEPLOYMENT_TYPE="Standard"
5+
DEPLOYMENT_TYPE="GlobalStandard"
66
CAPACITY=0
77

88
ALL_REGIONS=('australiaeast' 'eastus2' 'francecentral' 'japaneast' 'norwayeast' 'swedencentral' 'uksouth' 'westus')

src/backend/app_kernel.py

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@
3030
HumanClarification,
3131
HumanFeedback,
3232
InputTask,
33+
Plan,
34+
PlanStatus,
3335
PlanWithSteps,
3436
Step,
3537
UserLanguage,
@@ -292,6 +294,132 @@ async def input_task_endpoint(input_task: InputTask, request: Request):
292294
) from e
293295

294296

297+
@app.post("/api/create_plan")
298+
async def create_plan_endpoint(input_task: InputTask, request: Request):
299+
"""
300+
Create a new plan without full processing.
301+
302+
---
303+
tags:
304+
- Plans
305+
parameters:
306+
- name: user_principal_id
307+
in: header
308+
type: string
309+
required: true
310+
description: User ID extracted from the authentication header
311+
- name: body
312+
in: body
313+
required: true
314+
schema:
315+
type: object
316+
properties:
317+
session_id:
318+
type: string
319+
description: Session ID for the plan
320+
description:
321+
type: string
322+
description: The task description to validate and create plan for
323+
responses:
324+
200:
325+
description: Plan created successfully
326+
schema:
327+
type: object
328+
properties:
329+
plan_id:
330+
type: string
331+
description: The ID of the newly created plan
332+
status:
333+
type: string
334+
description: Success message
335+
session_id:
336+
type: string
337+
description: Session ID associated with the plan
338+
400:
339+
description: RAI check failed or invalid input
340+
schema:
341+
type: object
342+
properties:
343+
detail:
344+
type: string
345+
description: Error message
346+
"""
347+
# Perform RAI check on the description
348+
if not await rai_success(input_task.description):
349+
track_event_if_configured(
350+
"RAI failed",
351+
{
352+
"status": "Plan not created - RAI check failed",
353+
"description": input_task.description,
354+
"session_id": input_task.session_id,
355+
},
356+
)
357+
raise HTTPException(
358+
status_code=400,
359+
detail="Task description failed safety validation. Please revise your request."
360+
)
361+
362+
# Get authenticated user
363+
authenticated_user = get_authenticated_user_details(request_headers=request.headers)
364+
user_id = authenticated_user["user_principal_id"]
365+
366+
if not user_id:
367+
track_event_if_configured(
368+
"UserIdNotFound", {"status_code": 400, "detail": "no user"}
369+
)
370+
raise HTTPException(status_code=400, detail="no user")
371+
372+
# Generate session ID if not provided
373+
if not input_task.session_id:
374+
input_task.session_id = str(uuid.uuid4())
375+
376+
try:
377+
# Initialize memory store
378+
kernel, memory_store = await initialize_runtime_and_context(
379+
input_task.session_id, user_id
380+
)
381+
382+
# Create a new Plan object
383+
plan = Plan(
384+
session_id=input_task.session_id,
385+
user_id=user_id,
386+
initial_goal=input_task.description,
387+
overall_status=PlanStatus.in_progress,
388+
source=AgentType.PLANNER.value
389+
)
390+
391+
# Save the plan to the database
392+
await memory_store.add_plan(plan)
393+
394+
# Log successful plan creation
395+
track_event_if_configured(
396+
"PlanCreated",
397+
{
398+
"status": f"Plan created with ID: {plan.id}",
399+
"session_id": input_task.session_id,
400+
"plan_id": plan.id,
401+
"description": input_task.description,
402+
},
403+
)
404+
405+
return {
406+
"plan_id": plan.id,
407+
"status": "Plan created successfully",
408+
"session_id": input_task.session_id,
409+
}
410+
411+
except Exception as e:
412+
track_event_if_configured(
413+
"CreatePlanError",
414+
{
415+
"session_id": input_task.session_id,
416+
"description": input_task.description,
417+
"error": str(e),
418+
},
419+
)
420+
raise HTTPException(status_code=400, detail=f"Error creating plan: {e}")
421+
422+
295423
@app.post("/api/human_feedback")
296424
async def human_feedback_endpoint(human_feedback: HumanFeedback, request: Request):
297425
"""

0 commit comments

Comments
 (0)