salesforce-data-customcode 4.0.2__tar.gz → 5.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (98) hide show
  1. {salesforce_data_customcode-4.0.2 → salesforce_data_customcode-5.0.0}/PKG-INFO +1 -1
  2. {salesforce_data_customcode-4.0.2 → salesforce_data_customcode-5.0.0}/pyproject.toml +1 -1
  3. {salesforce_data_customcode-4.0.2 → salesforce_data_customcode-5.0.0}/src/datacustomcode/function/feature_types/chunking.py +14 -14
  4. salesforce_data_customcode-5.0.0/src/datacustomcode/templates/function/example/chunking_with_prediction/config.json +3 -0
  5. salesforce_data_customcode-5.0.0/src/datacustomcode/templates/function/example/chunking_with_prediction/entrypoint.py +251 -0
  6. salesforce_data_customcode-5.0.0/src/datacustomcode/templates/function/example/chunking_with_prediction/tests/test.json +40 -0
  7. {salesforce_data_customcode-4.0.2 → salesforce_data_customcode-5.0.0}/LICENSE.txt +0 -0
  8. {salesforce_data_customcode-4.0.2 → salesforce_data_customcode-5.0.0}/README.md +0 -0
  9. {salesforce_data_customcode-4.0.2 → salesforce_data_customcode-5.0.0}/src/datacustomcode/__init__.py +0 -0
  10. {salesforce_data_customcode-4.0.2 → salesforce_data_customcode-5.0.0}/src/datacustomcode/auth.py +0 -0
  11. {salesforce_data_customcode-4.0.2 → salesforce_data_customcode-5.0.0}/src/datacustomcode/cli.py +0 -0
  12. {salesforce_data_customcode-4.0.2 → salesforce_data_customcode-5.0.0}/src/datacustomcode/client.py +0 -0
  13. {salesforce_data_customcode-4.0.2 → salesforce_data_customcode-5.0.0}/src/datacustomcode/cmd.py +0 -0
  14. {salesforce_data_customcode-4.0.2 → salesforce_data_customcode-5.0.0}/src/datacustomcode/common_config.py +0 -0
  15. {salesforce_data_customcode-4.0.2 → salesforce_data_customcode-5.0.0}/src/datacustomcode/config.py +0 -0
  16. {salesforce_data_customcode-4.0.2 → salesforce_data_customcode-5.0.0}/src/datacustomcode/config.yaml +0 -0
  17. {salesforce_data_customcode-4.0.2 → salesforce_data_customcode-5.0.0}/src/datacustomcode/constants.py +0 -0
  18. {salesforce_data_customcode-4.0.2 → salesforce_data_customcode-5.0.0}/src/datacustomcode/credentials.py +0 -0
  19. {salesforce_data_customcode-4.0.2 → salesforce_data_customcode-5.0.0}/src/datacustomcode/deploy.py +0 -0
  20. {salesforce_data_customcode-4.0.2 → salesforce_data_customcode-5.0.0}/src/datacustomcode/einstein_platform_client.py +0 -0
  21. {salesforce_data_customcode-4.0.2 → salesforce_data_customcode-5.0.0}/src/datacustomcode/einstein_platform_config.py +0 -0
  22. {salesforce_data_customcode-4.0.2 → salesforce_data_customcode-5.0.0}/src/datacustomcode/einstein_predictions/__init__.py +0 -0
  23. {salesforce_data_customcode-4.0.2 → salesforce_data_customcode-5.0.0}/src/datacustomcode/einstein_predictions/base.py +0 -0
  24. {salesforce_data_customcode-4.0.2 → salesforce_data_customcode-5.0.0}/src/datacustomcode/einstein_predictions/impl/default.py +0 -0
  25. {salesforce_data_customcode-4.0.2 → salesforce_data_customcode-5.0.0}/src/datacustomcode/einstein_predictions/types.py +0 -0
  26. {salesforce_data_customcode-4.0.2 → salesforce_data_customcode-5.0.0}/src/datacustomcode/einstein_predictions_config.py +0 -0
  27. {salesforce_data_customcode-4.0.2 → salesforce_data_customcode-5.0.0}/src/datacustomcode/file/__init__.py +0 -0
  28. {salesforce_data_customcode-4.0.2 → salesforce_data_customcode-5.0.0}/src/datacustomcode/file/base.py +0 -0
  29. {salesforce_data_customcode-4.0.2 → salesforce_data_customcode-5.0.0}/src/datacustomcode/file/path/__init__.py +0 -0
  30. {salesforce_data_customcode-4.0.2 → salesforce_data_customcode-5.0.0}/src/datacustomcode/file/path/default.py +0 -0
  31. {salesforce_data_customcode-4.0.2 → salesforce_data_customcode-5.0.0}/src/datacustomcode/function/__init__.py +0 -0
  32. {salesforce_data_customcode-4.0.2 → salesforce_data_customcode-5.0.0}/src/datacustomcode/function/base.py +0 -0
  33. {salesforce_data_customcode-4.0.2 → salesforce_data_customcode-5.0.0}/src/datacustomcode/function/feature_types/__init__.py +0 -0
  34. {salesforce_data_customcode-4.0.2 → salesforce_data_customcode-5.0.0}/src/datacustomcode/function/runtime.py +0 -0
  35. {salesforce_data_customcode-4.0.2 → salesforce_data_customcode-5.0.0}/src/datacustomcode/function_utils.py +0 -0
  36. {salesforce_data_customcode-4.0.2 → salesforce_data_customcode-5.0.0}/src/datacustomcode/io/__init__.py +0 -0
  37. {salesforce_data_customcode-4.0.2 → salesforce_data_customcode-5.0.0}/src/datacustomcode/io/base.py +0 -0
  38. {salesforce_data_customcode-4.0.2 → salesforce_data_customcode-5.0.0}/src/datacustomcode/io/reader/__init__.py +0 -0
  39. {salesforce_data_customcode-4.0.2 → salesforce_data_customcode-5.0.0}/src/datacustomcode/io/reader/base.py +0 -0
  40. {salesforce_data_customcode-4.0.2 → salesforce_data_customcode-5.0.0}/src/datacustomcode/io/reader/query_api.py +0 -0
  41. {salesforce_data_customcode-4.0.2 → salesforce_data_customcode-5.0.0}/src/datacustomcode/io/reader/sf_cli.py +0 -0
  42. {salesforce_data_customcode-4.0.2 → salesforce_data_customcode-5.0.0}/src/datacustomcode/io/reader/utils.py +0 -0
  43. {salesforce_data_customcode-4.0.2 → salesforce_data_customcode-5.0.0}/src/datacustomcode/io/writer/__init__.py +0 -0
  44. {salesforce_data_customcode-4.0.2 → salesforce_data_customcode-5.0.0}/src/datacustomcode/io/writer/base.py +0 -0
  45. {salesforce_data_customcode-4.0.2 → salesforce_data_customcode-5.0.0}/src/datacustomcode/io/writer/csv.py +0 -0
  46. {salesforce_data_customcode-4.0.2 → salesforce_data_customcode-5.0.0}/src/datacustomcode/io/writer/print.py +0 -0
  47. {salesforce_data_customcode-4.0.2 → salesforce_data_customcode-5.0.0}/src/datacustomcode/llm_gateway/__init__.py +0 -0
  48. {salesforce_data_customcode-4.0.2 → salesforce_data_customcode-5.0.0}/src/datacustomcode/llm_gateway/base.py +0 -0
  49. {salesforce_data_customcode-4.0.2 → salesforce_data_customcode-5.0.0}/src/datacustomcode/llm_gateway/default.py +0 -0
  50. {salesforce_data_customcode-4.0.2 → salesforce_data_customcode-5.0.0}/src/datacustomcode/llm_gateway/types/__init__.py +0 -0
  51. {salesforce_data_customcode-4.0.2 → salesforce_data_customcode-5.0.0}/src/datacustomcode/llm_gateway/types/generate_text_request.py +0 -0
  52. {salesforce_data_customcode-4.0.2 → salesforce_data_customcode-5.0.0}/src/datacustomcode/llm_gateway/types/generate_text_request_builder.py +0 -0
  53. {salesforce_data_customcode-4.0.2 → salesforce_data_customcode-5.0.0}/src/datacustomcode/llm_gateway/types/generate_text_response.py +0 -0
  54. {salesforce_data_customcode-4.0.2 → salesforce_data_customcode-5.0.0}/src/datacustomcode/llm_gateway/types/generate_text_response_builder.py +0 -0
  55. {salesforce_data_customcode-4.0.2 → salesforce_data_customcode-5.0.0}/src/datacustomcode/llm_gateway_config.py +0 -0
  56. {salesforce_data_customcode-4.0.2 → salesforce_data_customcode-5.0.0}/src/datacustomcode/mixin.py +0 -0
  57. {salesforce_data_customcode-4.0.2 → salesforce_data_customcode-5.0.0}/src/datacustomcode/proxy/__init__.py +0 -0
  58. {salesforce_data_customcode-4.0.2 → salesforce_data_customcode-5.0.0}/src/datacustomcode/proxy/base.py +0 -0
  59. {salesforce_data_customcode-4.0.2 → salesforce_data_customcode-5.0.0}/src/datacustomcode/proxy/client/__init__.py +0 -0
  60. {salesforce_data_customcode-4.0.2 → salesforce_data_customcode-5.0.0}/src/datacustomcode/proxy/client/base.py +0 -0
  61. {salesforce_data_customcode-4.0.2 → salesforce_data_customcode-5.0.0}/src/datacustomcode/py.typed +0 -0
  62. {salesforce_data_customcode-4.0.2 → salesforce_data_customcode-5.0.0}/src/datacustomcode/run.py +0 -0
  63. {salesforce_data_customcode-4.0.2 → salesforce_data_customcode-5.0.0}/src/datacustomcode/scan.py +0 -0
  64. {salesforce_data_customcode-4.0.2 → salesforce_data_customcode-5.0.0}/src/datacustomcode/spark/__init__.py +0 -0
  65. {salesforce_data_customcode-4.0.2 → salesforce_data_customcode-5.0.0}/src/datacustomcode/spark/base.py +0 -0
  66. {salesforce_data_customcode-4.0.2 → salesforce_data_customcode-5.0.0}/src/datacustomcode/spark/default.py +0 -0
  67. {salesforce_data_customcode-4.0.2 → salesforce_data_customcode-5.0.0}/src/datacustomcode/template.py +0 -0
  68. {salesforce_data_customcode-4.0.2 → salesforce_data_customcode-5.0.0}/src/datacustomcode/templates/__init__.py +0 -0
  69. {salesforce_data_customcode-4.0.2 → salesforce_data_customcode-5.0.0}/src/datacustomcode/templates/function/.devcontainer/devcontainer.json +0 -0
  70. {salesforce_data_customcode-4.0.2 → salesforce_data_customcode-5.0.0}/src/datacustomcode/templates/function/Dockerfile.dependencies +0 -0
  71. {salesforce_data_customcode-4.0.2 → salesforce_data_customcode-5.0.0}/src/datacustomcode/templates/function/README.md +0 -0
  72. {salesforce_data_customcode-4.0.2 → salesforce_data_customcode-5.0.0}/src/datacustomcode/templates/function/build_native_dependencies.sh +0 -0
  73. {salesforce_data_customcode-4.0.2 → salesforce_data_customcode-5.0.0}/src/datacustomcode/templates/function/chunking/payload/config.json +0 -0
  74. {salesforce_data_customcode-4.0.2 → salesforce_data_customcode-5.0.0}/src/datacustomcode/templates/function/chunking/payload/entrypoint.py +0 -0
  75. {salesforce_data_customcode-4.0.2 → salesforce_data_customcode-5.0.0}/src/datacustomcode/templates/function/chunking/requirements.txt +0 -0
  76. {salesforce_data_customcode-4.0.2 → salesforce_data_customcode-5.0.0}/src/datacustomcode/templates/function/example/chunking_with_llm/config.json +0 -0
  77. {salesforce_data_customcode-4.0.2 → salesforce_data_customcode-5.0.0}/src/datacustomcode/templates/function/example/chunking_with_llm/entrypoint.py +0 -0
  78. {salesforce_data_customcode-4.0.2 → salesforce_data_customcode-5.0.0}/src/datacustomcode/templates/function/example/chunking_with_llm/files/chunking_prompt.txt +0 -0
  79. {salesforce_data_customcode-4.0.2 → salesforce_data_customcode-5.0.0}/src/datacustomcode/templates/function/example/chunking_with_llm/tests/test.json +0 -0
  80. {salesforce_data_customcode-4.0.2 → salesforce_data_customcode-5.0.0}/src/datacustomcode/templates/function/payload/config.json +0 -0
  81. {salesforce_data_customcode-4.0.2 → salesforce_data_customcode-5.0.0}/src/datacustomcode/templates/function/payload/entrypoint.py +0 -0
  82. {salesforce_data_customcode-4.0.2 → salesforce_data_customcode-5.0.0}/src/datacustomcode/templates/function/requirements-dev.txt +0 -0
  83. {salesforce_data_customcode-4.0.2 → salesforce_data_customcode-5.0.0}/src/datacustomcode/templates/function/requirements.txt +0 -0
  84. {salesforce_data_customcode-4.0.2 → salesforce_data_customcode-5.0.0}/src/datacustomcode/templates/script/.devcontainer/devcontainer.json +0 -0
  85. {salesforce_data_customcode-4.0.2 → salesforce_data_customcode-5.0.0}/src/datacustomcode/templates/script/Dockerfile +0 -0
  86. {salesforce_data_customcode-4.0.2 → salesforce_data_customcode-5.0.0}/src/datacustomcode/templates/script/Dockerfile.dependencies +0 -0
  87. {salesforce_data_customcode-4.0.2 → salesforce_data_customcode-5.0.0}/src/datacustomcode/templates/script/README.md +0 -0
  88. {salesforce_data_customcode-4.0.2 → salesforce_data_customcode-5.0.0}/src/datacustomcode/templates/script/account.ipynb +0 -0
  89. {salesforce_data_customcode-4.0.2 → salesforce_data_customcode-5.0.0}/src/datacustomcode/templates/script/build_native_dependencies.sh +0 -0
  90. {salesforce_data_customcode-4.0.2 → salesforce_data_customcode-5.0.0}/src/datacustomcode/templates/script/examples/employee_hierarchy/employee_data.csv +0 -0
  91. {salesforce_data_customcode-4.0.2 → salesforce_data_customcode-5.0.0}/src/datacustomcode/templates/script/examples/employee_hierarchy/entrypoint.py +0 -0
  92. {salesforce_data_customcode-4.0.2 → salesforce_data_customcode-5.0.0}/src/datacustomcode/templates/script/jupyterlab.sh +0 -0
  93. {salesforce_data_customcode-4.0.2 → salesforce_data_customcode-5.0.0}/src/datacustomcode/templates/script/payload/config.json +0 -0
  94. {salesforce_data_customcode-4.0.2 → salesforce_data_customcode-5.0.0}/src/datacustomcode/templates/script/payload/entrypoint.py +0 -0
  95. {salesforce_data_customcode-4.0.2 → salesforce_data_customcode-5.0.0}/src/datacustomcode/templates/script/requirements-dev.txt +0 -0
  96. {salesforce_data_customcode-4.0.2 → salesforce_data_customcode-5.0.0}/src/datacustomcode/templates/script/requirements.txt +0 -0
  97. {salesforce_data_customcode-4.0.2 → salesforce_data_customcode-5.0.0}/src/datacustomcode/token_provider.py +0 -0
  98. {salesforce_data_customcode-4.0.2 → salesforce_data_customcode-5.0.0}/src/datacustomcode/version.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: salesforce-data-customcode
3
- Version: 4.0.2
3
+ Version: 5.0.0
4
4
  Summary: Data Cloud Custom Code SDK
5
5
  License-Expression: Apache-2.0
6
6
  License-File: LICENSE.txt
@@ -18,7 +18,7 @@ license = "Apache-2.0"
18
18
  name = "salesforce-data-customcode"
19
19
  readme = "README.md"
20
20
  requires-python = ">=3.10,<3.12"
21
- version = "4.0.2"
21
+ version = "5.0.0"
22
22
 
23
23
  [tool.black]
24
24
  exclude = '''
@@ -31,8 +31,8 @@ from pydantic import (
31
31
  )
32
32
 
33
33
 
34
- class DocumentType(str, Enum):
35
- """Document type enumeration"""
34
+ class ElementType(str, Enum):
35
+ """Element type enumeration"""
36
36
 
37
37
  TEXT = "text"
38
38
  TITLE = "title"
@@ -74,15 +74,15 @@ class SearchIndexChunkingV1TranscriptField(BaseModel):
74
74
  description="Speaker name for audio/video transcripts",
75
75
  examples=["Agent"],
76
76
  )
77
- start_timestamp: Optional[str] = Field(
77
+ start_timestamp: Optional[float] = Field(
78
78
  default=None,
79
- description="Start timestamp in ISO8601 format: YYYY-MM-DDTHH:MM:SS.ffffff",
80
- examples=["2026-03-25T02:01:24.918000"],
79
+ description="Start timestamp of the audio/video clip",
80
+ examples=["1.0"],
81
81
  )
82
- end_timestamp: Optional[str] = Field(
82
+ end_timestamp: Optional[float] = Field(
83
83
  default=None,
84
- description="End timestamp in ISO8601 format: YYYY-MM-DDTHH:MM:SS.ffffff",
85
- examples=["2026-03-25T02:01:30.500000"],
84
+ description="End timestamp of the audio/video clip",
85
+ examples=["8.75"],
86
86
  )
87
87
  model_config = ConfigDict(extra="ignore")
88
88
 
@@ -90,16 +90,16 @@ class SearchIndexChunkingV1TranscriptField(BaseModel):
90
90
  class SearchIndexChunkingV1Metadata(BaseModel):
91
91
  """Metadata for input documents."""
92
92
 
93
- type: Optional[DocumentType] = Field(
94
- default=DocumentType.TEXT,
93
+ type: Optional[ElementType] = Field(
94
+ default=ElementType.TEXT,
95
95
  description=(
96
- "Document type of the chunk input. Currently only 'text' is supported."
96
+ "Element type of the chunk input. Currently only 'text' is supported."
97
97
  ),
98
98
  examples=["text"],
99
99
  )
100
100
  page_number: Optional[int] = Field(
101
101
  default=None,
102
- description=("Page number in the source document (0-based). "),
102
+ description=("Page number in the source document."),
103
103
  examples=[1],
104
104
  )
105
105
  transcript_fields: Optional[SearchIndexChunkingV1TranscriptField] = Field(
@@ -111,7 +111,7 @@ class SearchIndexChunkingV1Metadata(BaseModel):
111
111
  )
112
112
  text_as_html: Optional[str] = Field(
113
113
  default=None,
114
- description=("HTML representation of the chunk text, if available. "),
114
+ description=("Table represented as HTML"),
115
115
  examples=["<p>Online Remittance Instructions</p>"],
116
116
  )
117
117
  source_dmo_fields: Optional[Dict[str, Union[str, int, float]]] = Field(
@@ -194,7 +194,7 @@ class SearchIndexChunkingV1Output(BaseModel):
194
194
  examples=["Online Remittance Instructions"],
195
195
  )
196
196
  seq_no: int = Field(
197
- default=0,
197
+ default=1,
198
198
  description=(
199
199
  "Sequential order of this chunk within the output "
200
200
  "Represents chunk ordering within the source document (1-based)."
@@ -0,0 +1,251 @@
1
+ #!/usr/bin/env python3
2
+ # Copyright (c) 2025, Salesforce, Inc.
3
+ # SPDX-License-Identifier: Apache-2
4
+
5
+ """
6
+ Housing Sale Price Prediction with Einstein Regression
7
+
8
+ This example uses Einstein regression model to predict housing sale prices
9
+ based on property features like Year_Built__c.
10
+
11
+ Model: YH_Regression_Python_Predicted_SalePrice_CM_12l_ATC937af934
12
+ Type: Regression
13
+ Input: Year_Built__c (numeric)
14
+ Output: Predicted_SalePrice
15
+ """
16
+
17
+ import logging
18
+ from typing import (
19
+ Any,
20
+ Dict,
21
+ Optional,
22
+ )
23
+
24
+ from datacustomcode.einstein_predictions.types import (
25
+ PredictionColumBuilder,
26
+ PredictionRequestBuilder,
27
+ PredictionType,
28
+ )
29
+ from datacustomcode.function import Runtime
30
+ from datacustomcode.function.feature_types.chunking import (
31
+ ChunkType,
32
+ SearchIndexChunkingV1Output,
33
+ SearchIndexChunkingV1Request,
34
+ SearchIndexChunkingV1Response,
35
+ )
36
+
37
+ logger = logging.getLogger(__name__)
38
+ logging.basicConfig(level=logging.INFO)
39
+
40
+ # Configuration
41
+ PREDICTION_MODEL_NAME = "YH_Regression_Python_Predicted_SalePrice_CM_12l_ATC937af934"
42
+
43
+
44
+ def predict_sale_price(
45
+ features: Dict[str, Any],
46
+ runtime: Runtime,
47
+ ) -> Optional[float]:
48
+ """Predict housing sale price using Einstein regression model.
49
+
50
+ Args:
51
+ features: Extracted housing features (numeric and string)
52
+ runtime: Runtime with prediction client
53
+
54
+ Returns:
55
+ Predicted sale price or None if prediction fails
56
+ """
57
+ try:
58
+ # Build prediction columns - handle both numeric and string values
59
+ prediction_columns = []
60
+
61
+ for column_name, value in features.items():
62
+ if isinstance(value, str):
63
+ # String values (e.g., Garage_Qual__c)
64
+ column = (
65
+ PredictionColumBuilder()
66
+ .set_column_name(column_name)
67
+ .set_string_values([value])
68
+ .build()
69
+ )
70
+ elif isinstance(value, (int, float)):
71
+ # Numeric values
72
+ column = (
73
+ PredictionColumBuilder()
74
+ .set_column_name(column_name)
75
+ .set_double_values([float(value)])
76
+ .build()
77
+ )
78
+ else:
79
+ # Skip unsupported types
80
+ logger.warning(
81
+ f"Skipping field {column_name} with unsupported type {type(value)}"
82
+ )
83
+ continue
84
+
85
+ prediction_columns.append(column)
86
+
87
+ # Build regression prediction request
88
+ prediction_request = (
89
+ PredictionRequestBuilder()
90
+ .set_prediction_type(PredictionType.REGRESSION)
91
+ .set_model_api_name(PREDICTION_MODEL_NAME)
92
+ .set_prediction_columns(prediction_columns)
93
+ .build()
94
+ )
95
+
96
+ logger.info(f"Model: {PREDICTION_MODEL_NAME}")
97
+
98
+ prediction_response = runtime.einstein_predictions.predict(prediction_request)
99
+
100
+ logger.info(f"Response status code: {prediction_response.status_code}")
101
+ logger.info(f"Response data: {prediction_response.data}")
102
+
103
+ if not prediction_response.is_success:
104
+ logger.error(f"Prediction failed: {prediction_response.data}")
105
+ return None
106
+
107
+ # Parse regression response
108
+ if prediction_response.data is None:
109
+ logger.warning("Prediction response data is None")
110
+ return None
111
+
112
+ results = prediction_response.data.get("results", [])
113
+ if not results:
114
+ logger.warning("No results in prediction response")
115
+ return None
116
+
117
+ first_result = results[0]
118
+ prediction_type = first_result.get("type")
119
+
120
+ if prediction_type != "RegressionPredictionSuccess":
121
+ logger.error(f"Unexpected prediction type: {prediction_type}")
122
+ logger.error(f"Full result: {first_result}")
123
+ return None
124
+
125
+ prediction_data = first_result.get("prediction", {})
126
+ predicted_value = prediction_data.get("predictedValue")
127
+
128
+ if predicted_value is None:
129
+ logger.warning("No predicted value in response")
130
+ return None
131
+
132
+ logger.info(f"Predicted sale price: ${predicted_value:,.2f}")
133
+
134
+ # Log top contributors (which features influenced the price most)
135
+ top_contributors = prediction_data.get("topContributors", [])
136
+ if top_contributors:
137
+ logger.info(f"Top price contributors: {top_contributors}")
138
+
139
+ return float(predicted_value)
140
+
141
+ except Exception as e:
142
+ logger.error(f"Prediction failed with error: {e}", exc_info=True)
143
+ return None
144
+
145
+
146
+ def enrich_property_with_price(
147
+ source_dmo_fields: Dict[str, Any],
148
+ runtime: Runtime,
149
+ ) -> Dict[str, str]:
150
+ """Enrich property data with predicted sale price.
151
+
152
+ Args:
153
+ source_dmo_fields: Property features from source DMO
154
+ runtime: Runtime for predictions
155
+
156
+ Returns:
157
+ Citations dictionary with predicted price
158
+ """
159
+ citations = {}
160
+
161
+ # Copy original fields to citations
162
+ if source_dmo_fields:
163
+ for key, value in source_dmo_fields.items():
164
+ citations[key] = str(value)
165
+
166
+ # Get price prediction - pass source_dmo_fields directly as features
167
+ predicted_price = predict_sale_price(source_dmo_fields, runtime)
168
+
169
+ if predicted_price is not None:
170
+ citations["predicted_sale_price"] = f"${predicted_price:,.2f}"
171
+ citations["predicted_sale_price_raw"] = str(predicted_price)
172
+ citations["prediction_status"] = "success"
173
+ else:
174
+ citations["predicted_sale_price"] = "N/A"
175
+ citations["prediction_status"] = "failed"
176
+
177
+ return citations
178
+
179
+
180
+ def function(
181
+ request: SearchIndexChunkingV1Request, runtime: Runtime
182
+ ) -> SearchIndexChunkingV1Response:
183
+ """Housing price prediction using Einstein regression.
184
+
185
+ Predicts sale prices for properties based on Year_Built__c feature
186
+ and adds predictions to citations for real estate data enrichment.
187
+
188
+ Input format:
189
+ {
190
+ "input": [
191
+ {
192
+ "text": "Beautiful 3BR house built in 1990",
193
+ "metadata": {
194
+ "source_dmo_fields": {
195
+ "Year_Built__c": 1990,
196
+ }
197
+ }
198
+ }
199
+ ]
200
+ }
201
+
202
+ Output format:
203
+ {
204
+ "output": [
205
+ {
206
+ "text": "Beautiful 3BR house built in 1990",
207
+ "seq_no": 1,
208
+ "citations": {
209
+ "Year_Built__c": "1990",
210
+ "predicted_sale_price": "$350,000.00",
211
+ "predicted_sale_price_raw": "350000.0",
212
+ "prediction_status": "success"
213
+ }
214
+ }
215
+ ]
216
+ }
217
+
218
+ Args:
219
+ request: Input properties to enrich
220
+ runtime: Runtime with prediction API access
221
+
222
+ Returns:
223
+ Properties enriched with predicted sale prices
224
+ """
225
+
226
+ enriched_properties = []
227
+ seq_no = 1
228
+
229
+ for doc_idx, doc in enumerate(request.input):
230
+ text = doc.text
231
+ metadata = doc.metadata
232
+
233
+ source_dmo_fields = {}
234
+ if metadata and metadata.source_dmo_fields:
235
+ source_dmo_fields = dict(metadata.source_dmo_fields)
236
+
237
+ # Enrich with price prediction - pass source_dmo_fields directly
238
+ citations = enrich_property_with_price(source_dmo_fields, runtime)
239
+
240
+ # Create output
241
+ property_output = SearchIndexChunkingV1Output(
242
+ chunk_type=ChunkType.TEXT,
243
+ text=text.strip(),
244
+ seq_no=seq_no,
245
+ citations=citations,
246
+ )
247
+ enriched_properties.append(property_output)
248
+
249
+ seq_no += 1
250
+
251
+ return SearchIndexChunkingV1Response(output=enriched_properties)
@@ -0,0 +1,40 @@
1
+ {
2
+ "input": [
3
+ {
4
+ "text": "Luxury 5-bedroom house with 5000 sq ft living area, built in 2023",
5
+ "metadata": {
6
+ "type": "text",
7
+ "source_dmo_fields": {
8
+ "First_Flr_SF__c": 2600,
9
+ "Full_Bath__c": 4,
10
+ "Garage_Cars__c": 4,
11
+ "Garage_Qual__c": "good",
12
+ "Gr_Liv_Area__c": 5000,
13
+ "Lot_Area__c": 3000,
14
+ "Overall_Cond__c": 10,
15
+ "Second_Flr_SF__c": 2400,
16
+ "Total_Bsmt_SF__c": 0,
17
+ "Year_Built__c": 2023
18
+ }
19
+ }
20
+ },
21
+ {
22
+ "text": "Spacious 4-bedroom family home with 3500 sq ft living space, built in 2020",
23
+ "metadata": {
24
+ "type": "text",
25
+ "source_dmo_fields": {
26
+ "First_Flr_SF__c": 2000,
27
+ "Full_Bath__c": 3,
28
+ "Garage_Cars__c": 3,
29
+ "Garage_Qual__c": "excellent",
30
+ "Gr_Liv_Area__c": 3500,
31
+ "Lot_Area__c": 8000,
32
+ "Overall_Cond__c": 9,
33
+ "Second_Flr_SF__c": 1500,
34
+ "Total_Bsmt_SF__c": 1000,
35
+ "Year_Built__c": 2020
36
+ }
37
+ }
38
+ }
39
+ ]
40
+ }